OpenLayers 2 has these layer events "loadstart & loadend."
What is equivalent to them in OpenLayers 3?
While a vector layer loads and is rendered, I need to show a loading icon.
OpenLayers 2 has these layer events "loadstart & loadend."
What is equivalent to them in OpenLayers 3?
While a vector layer loads and is rendered, I need to show a loading icon.
Assuming you use an ol.layer.Vector
with an ol.source.GeoJSON
you can use something like this:
var vectorSource = new ol.source.GeoJSON({
projection : 'EPSG:3857',
url: 'http://examples.org/fearures.json'
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map.addLayer(vectorLayer);
// show loading icon
// ...
var listenerKey = vectorSource.on('change', function(e) {
if (vectorSource.getState() == 'ready') {
// hide loading icon
// ...
// and unregister the "change" listener
ol.Observable.unByKey(listenerKey);
// or vectorSource.unByKey(listenerKey) if
// you don't use the current master branch
// of ol3
}
});
This shows how to get a notification when the vector source is loaded. It only works with sources inheriting from ol.source.StaticVector
. Examples include ol.source.GeoJSON
and ol.source.KML
.
Also, note that this code may no longer work in the future when ol3 will provide a consistent way to know if/when a source is loaded.
In ol3 version 3.10.0 things have changed. So is more clear than older versions but still more complicated than ol2.
So for TILE (ol.layer.Tile) layers your code snip should look like:
//declare the layer
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
//asign the listeners on the source of tile layer
osmLayer.getSource().on('tileloadstart', function(event) {
//replace with your custom action
document.getElementById('tilesloaderindicatorimg').src = 'css/images/tree_loading.gif';
});
osmLayer.getSource().on('tileloadend', function(event) {
//replace with your custom action
document.getElementById('tilesloaderindicatorimg').src = 'css/images/ok.png';
});
osmLayer.getSource().on('tileloaderror', function(event) {
//replace with your custom action
document.getElementById('tilesloaderindicatorimg').src = 'css/images/no.png';
});
while for WMS layers the approach is a bit different:
//declare the layer
var wmsLayer = new ol.layer.Image({
source: new ol.source.ImageWMS({
attributions: [new ol.Attribution({
html: '© ' +
'<a href="http://www.geo.admin.ch/internet/geoportal/' +
'en/home.html">' +
'National parks / geo.admin.ch</a>'
})],
crossOrigin: 'anonymous',
params: {'LAYERS': 'ch.bafu.schutzgebiete-paerke_nationaler_bedeutung'},
serverType: 'mapserver',
url: 'http://wms.geo.admin.ch/'
})
});
//and now asign the listeners on the source of it
var lyrSource = wmsLayer.getSource();
lyrSource.on('imageloadstart', function(event) {
console.log('imageloadstart event',event);
//replace with your custom action
var elemId = event.target.params_.ELEMENTID;
document.getElementById(elemId).src = 'css/images/tree_loading.gif';
});
lyrSource.on('imageloadend', function(event) {
console.log('imageloadend event',event);
//replace with your custom action
var elemId = event.target.params_.ELEMENTID;
document.getElementById(elemId).src = 'css/images/ok.png';
});
lyrSource.on('imageloaderror', function(event) {
console.log('imageloaderror event',event);
//replace with your custom action
var elemId = event.target.params_.ELEMENTID;
document.getElementById(elemId).src = 'css/images/no.png';
});
For WFS Vector layers things are even more complicated:
//declare the vector source
sourceVector = new ol.source.Vector({
loader: function (extent) {
//START LOADING
//place here any actions on start loading layer
document.getElementById('laodingcont').innerHTML = "<font color='orange'>start loading.....</font>";
$.ajax('http://demo.opengeo.org/geoserver/wfs', {
type: 'GET',
data: {
service: 'WFS',
version: '1.1.0',
request: 'GetFeature',
typename: 'water_areas',
srsname: 'EPSG:3857',
bbox: extent.join(',') + ',EPSG:3857'
}
}).done(loadFeatures)
.fail(function () {
//FAIL LOADING
//place here any actions on fail loading layer
document.getElementById('laodingcont').innerHTML = "<font color='red'>error loading vector layer.</font>";
});
},
strategy: ol.loadingstrategy.bbox
});
//once we have a success responce, we need to parse it and add fetaures on map
function loadFeatures(response) {
formatWFS = new ol.format.WFS(),
sourceVector.addFeatures(formatWFS.readFeatures(response));
//FINISH LOADING
document.getElementById('laodingcont').innerHTML = "<font color='green'>finish loading vector layer.</font>";
}
check this post. it has all the above + a fiddle for the WFS vector layers
I have not found the class ol.source.GeoJSON
, and could not find a case where vectorSource.getState() != 'ready'
. So I ended up doing something like this:
function spin(active) {
if (active) {
// start spinning the spinner
} else {
// stop spinning the spinner
}
}
// Toggle spinner on layer loading
layer.on('change', function() {
spin();
});
layer.getSource().on('change', function() {
spin(false);
});
you can also use the getState() function
if (source instanceof ol.source.Vector) {
source.on("change", function () {
//console.log("Vector change, state: " + source.getState());
switch (source.getState()) {
case "loading":
$("#ajaxSpinnerImage").show();
break;
default:
$("#ajaxSpinnerImage").hide();
}
});
}
On OL 4.5.0, for vector layers I haven't found a way to deal with the source, instead I use the following on the layer events:
if (layer instanceof ol.layer.Vector) {
layer.on("precompose", function () {
$("#ajaxSpinnerImage").show();
});
layer.on("render", function () {
$("#ajaxSpinnerImage").hide();
});
}
Hope it can help.