OpenLayers 3: Wie überprüfe ich, ob die Vektorquelle bereit ist?

8

ol.source.getState()scheint nicht zuverlässig zu sein. Wenn ich es auf einer Vektorquelle aufrufe, wird es bereit zurückgegeben, aber die Funktionen sind noch nicht verfügbar. Code sieht so aus:

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

Gibt es eine andere Möglichkeit, um festzustellen, ob eine Vektorquelle bereit ist?

johjoh
quelle
Haben Sie überprüft, ob diese Funktions-ID vorhanden ist?
Jonatas Walker
@ JonatasWalker, ja es existiert.
Johjoh

Antworten:

8

Sie können Ihre eigene Loader-Funktion bereitstellen und einige benutzerdefinierte Listener wie folgt festlegen:

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

Stellen Sie einige benutzerdefinierte Listener ein:

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

Und eine xhr-Funktion:

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

Arbeitsdemo .

Jonatas Walker
quelle
Das funktioniert gut! Entschuldigung für die verspätete Genehmigung. Vor zwei Jahren habe ich es nicht wirklich verstanden und meine eigene Lösung gefunden - die, wie sich herausstellte, nicht zuverlässig war.
Johjoh
3

Sie können einen Listener an Ihre vectorSource http://openlayers.org/en/v3.7.0/apidoc/ol.source.Vector.html#once anhängen

z.B

vectorSource.once('change',function(e){
    if (vectorSource.getState() === 'ready') {
        vectorSource.getFeatureById("US");
    }
});
Kerl
quelle
Ja, das mache ich bereits, aber das Ereignis wird nicht ausgelöst, wenn die Quelle bereits zuvor geladen wurde. Also wollte ich überprüfen, ob die Quelle bereit ist. Wenn ja, arbeiten Sie sofort daran - wenn nicht, binden Sie es an das Änderungsereignis.
Johjoh
0

Am Ende hatte ich die folgende Funktion, um Code auszuführen, wenn die Vektorquelle bereit ist:

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

Ich bin mir nicht sicher, ob das Testen auf eine einzelne Funktion zuverlässig ist, da möglicherweise nicht alle Funktionen gleichzeitig verfügbar sind.

johjoh
quelle
Dies ist nicht zuverlässig, wie sich jetzt herausstellte. Wenn Sie nach einer Funktion suchen, können Sie nicht feststellen, ob die anderen vorhanden sind. Siehe die akzeptierte Antwort. Es funktioniert gut für mich.
Johjoh