Vous utilisez des événements de démarrage et de chargement de couches dans OpenLayers 3?

19

OpenLayers 2 a ces événements de couche "loadstart & loadend".

Qu'est-ce qui leur est équivalent dans OpenLayers 3?

Pendant qu'un calque vectoriel se charge et est rendu, je dois montrer une icône de chargement.

Mariam Malak
la source
Quel type de source vectorielle utilisez-vous? Pouvez-vous s'il vous plaît fournir un peu plus de contexte?
erilem

Réponses:

19

En supposant que vous utilisez un ol.layer.Vectoravec un, ol.source.GeoJSONvous pouvez utiliser quelque chose comme ceci:

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
  }
});

Cela montre comment obtenir une notification lorsque la source vectorielle est chargée. Il ne fonctionne qu'avec des sources héritées de ol.source.StaticVector. Les exemples incluent ol.source.GeoJSONet ol.source.KML.

Notez également que ce code risque de ne plus fonctionner à l'avenir lorsque ol3 fournira un moyen cohérent de savoir si / quand une source est chargée.

erilem
la source
Génial! Je le cherchais aussi. Vous vous demandez pourquoi OL3 ne l'inclut pas encore.
Germán Carrillo
Pourquoi ne pas vectorSource.once('change', function(e){...}?
Jonatas Walker
14

Dans la version 3.10.0 de l'ol3, les choses ont changé. C'est donc plus clair que les anciennes versions mais toujours plus compliqué que ol2.

Ainsi, pour les couches TILE (ol.layer.Tile), votre extrait de code devrait ressembler à:

//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';
 });

tandis que pour les couches WMS, l'approche est un peu différente:

//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'; 
  }); 

Pour les couches vectorielles WFS, les choses sont encore plus compliquées:

//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>";
}

consultez ce post. il a tout ce qui précède + un violon pour les couches vectorielles WFS

pavlos
la source
1
Bienvenue sur GIS.SE! Pouvez-vous développer votre réponse et fournir un bref résumé de l'article auquel vous avez lié et quelle partie est pertinente pour la réponse à cette question. De cette façon, la réponse pourra aider les gens sur ce site, même après la mort du lien.
Kersten
désolé newby. terminé!!!!!!!!
pavlos
pour vérifier quel type de couche vous avez, voici comment vous pouvez le faire pour OL3 gis.stackexchange.com/a/140852/63141
Daniël Tulp
Cela devrait être la meilleure réponse!
joaorodr84
1
S'il vous plaît les gars de l'OL .... KISS man ... KISS ....
Magno C
2

Je n'ai pas trouvé la classe ol.source.GeoJSONet n'ai pas pu trouver un cas où vectorSource.getState() != 'ready'. J'ai donc fini par faire quelque chose comme ça:

    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);
    });
Damien
la source
veuillez également poster la fonction de rotation, il semble que vous les faites tourner et ne les arrêtez pas à la fin du chargement de la couche
Daniël Tulp
1

vous pouvez également utiliser la getState () fonction

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();
            }
        });
    }
Daniël Tulp
la source
J'utilise ol-v4.2.0. source.getState()renvoie toujours «prêt»
himyata
1

Sur OL 4.5.0, pour les couches vectorielles, je n'ai pas trouvé de moyen de gérer la source, mais j'utilise à la place les éléments suivants sur les événements de couche:

if (layer instanceof ol.layer.Vector) {
    layer.on("precompose", function () {
              $("#ajaxSpinnerImage").show();
            });
    layer.on("render", function () {
              $("#ajaxSpinnerImage").hide();
            });
}

J'espère que cela peut aider.

jean pierre huart
la source