OpenLayers 3: ¿Cómo verificar si la fuente del vector está lista?

8

ol.source.getState()No parece ser confiable. Cuando lo llamo en una fuente vectorial, vuelve listo, pero las características aún no están disponibles. El código se ve así:

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

¿Alguna otra forma de ver si una fuente vectorial está lista?

johjoh
fuente
¿Verificaste si esta ID de función existe?
Jonatas Walker
@JonatasWalker, sí, existe.
johjoh

Respuestas:

8

Puede proporcionar su propia función de cargador y configurar algunos oyentes personalizados, como se indica a continuación:

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

Establecer algunos oyentes 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');
});

Y una función 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);
};

Demo de trabajo .

Jonatas Walker
fuente
Esto funciona bien! Perdón por la aprobación tardía. Hace dos años realmente no lo entendí y encontré mi propia solución , que no era confiable como resultó ahora.
johjoh
3

Puede adjuntar un oyente a su vectorSource http://openlayers.org/en/v3.7.0/apidoc/ol.source.Vector.html#once

p.ej

vectorSource.once('change',function(e){
    if (vectorSource.getState() === 'ready') {
        vectorSource.getFeatureById("US");
    }
});
Chico
fuente
Sí, eso es lo que ya hago, pero el evento no se disparará, si la fuente ya se cargó antes. Así que quería verificar si la fuente está lista. Si es así, trabaje de inmediato, si no, vincúlelo al evento de cambio.
johjoh
0

Terminé con la siguiente función, ejecutar código cuando la fuente del vector está lista:

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

No estoy seguro de si la prueba para una sola función es confiable, como podría ser, que no todas las funciones estén disponibles al mismo tiempo.

johjoh
fuente
Esto no es confiable, como resultó ahora. Al verificar una característica, no se dice si hay otras. Ver la respuesta aceptada. Funciona bien para mi
johjoh