OpenLayers 3: Como verificar se a fonte do vetor está pronta?

8

ol.source.getState()não parece ser confiável. Quando eu chamo isso em uma fonte vetorial, ele volta pronto, mas os recursos ainda não estão disponíveis. O código fica assim:

var vectorSource = new ol.source.Vector({
  url: 'world.topo.json',
  format: new ol.format.TopoJSON()
});

// ... init map with vectorSource

console.log(vectorSource.getState()); // returns "ready"
console.log(vectorSource.getFeatureById("US")); // returns null

Alguma outra maneira de verificar se uma fonte vetorial está pronta?

johjoh
fonte
Você verificou se esse ID do recurso existe?
Jonatas Walker
@JonatasWalker, sim, existe.
Johjoh 14/07/2015

Respostas:

8

Você pode fornecer sua própria função de carregador e definir alguns ouvintes personalizados, conforme a seguir:

var source = new ol.source.Vector({
    loader: function(){
        var url = '....../data/json/world-110m.json';
        var format = new ol.format.TopoJSON();
        var source = this;

        //dispatch your custom event
        this.set('loadstart', Math.random());

        getJson(url, '', function(response){

            if(Object.keys(response).length > 0){
                var features = format.readFeatures(response, {
                    featureProjection: 'EPSG:3857'
                });
                source.addFeatures(features);
                //dispatch your custom event
                source.set('loadend', Math.random());
            }
        });
    }
});

Defina alguns ouvintes personalizados:

//custom source listener
source.set('loadstart', '');
source.set('loadend', '');

source.on('change:loadstart', function(evt){
    console.info('loadstart');
});
source.on('change:loadend', function(evt){
    console.info('loadend');
});

E uma função xhr:

var getJson = function(url, data, callback) {

    // Must encode data
    if(data && typeof(data) === 'object') {
        var y = '', e = encodeURIComponent;
        for (x in data) {
            y += '&' + e(x) + '=' + e(data[x]);
        }
        data = y.slice(1);
        url += (/\?/.test(url) ? '&' : '?') + data;
    }

    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", url, true);
    xmlHttp.setRequestHeader('Accept', 'application/json, text/javascript');
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttp.onreadystatechange = function () {
        if (xmlHttp.readyState != 4){
            return;
        }
        if (xmlHttp.status != 200 && xmlHttp.status != 304){
            callback('');
            return;
        }
        callback(JSON.parse(xmlHttp.response));
    };
    xmlHttp.send(null);
};

Demonstração de trabalho .

Jonatas Walker
fonte
Isso funciona bem! Desculpe pela aprovação tardia. Dois anos atrás, eu realmente não o entendi e encontrei minha própria solução - que não era confiável como era agora.
Johjoh 4/04
3

Você pode anexar um ouvinte ao seu vectorSource http://openlayers.org/en/v3.7.0/apidoc/ol.source.Vector.html#once

por exemplo

vectorSource.once('change',function(e){
    if (vectorSource.getState() === 'ready') {
        vectorSource.getFeatureById("US");
    }
});
Cara
fonte
Sim, é isso que eu já faço, mas o evento não será acionado, se a fonte já tiver sido carregada antes. Então, eu queria verificar se a fonte está pronta. Se assim for, trabalhe imediatamente - se não, vincule-o ao evento de mudança.
johjoh
0

Acabei com a seguinte função, para executar o código quando a fonte do vetor estiver pronta:

doWhenVectorSourceReady : function(callback) {
  var map = this;

  if (map.vectorSource.getFeatureById("US")) { // Is this a relieable test?
    callback();
  } else {
    var listener = map.vectorSource.on('change', function(e) {
      if (map.vectorSource.getState() == 'ready') {
        ol.Observable.unByKey(listener);
        callback();
      }
    });
  }
}

Não tenho certeza se o teste de um único recurso é confiável, como pode ser, que nem todos os recursos sejam disponibilizados ao mesmo tempo.

johjoh
fonte
Isso não é confiável, como se viu agora. A verificação de um recurso não informa se os outros estão lá. Veja a resposta aceita. Funciona bem para mim.
Johjoh 4/04