OpenLayers 3: Bagaimana cara memeriksa apakah sumber vektor siap?

8

ol.source.getState()sepertinya tidak bisa diandalkan. Ketika saya menyebutnya pada sumber vektor, ia kembali siap, tetapi fitur-fiturnya belum tersedia. Kode terlihat seperti ini:

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

Adakah cara lain untuk melihat apakah sumber vektor sudah siap?

johjoh
sumber
Apakah Anda memeriksa apakah ID fitur ini ada?
Jonatas Walker
@JonatasWalker, ya itu ada.
johjoh

Jawaban:

8

Anda dapat menyediakan fungsi pemuat Anda sendiri dan mengatur beberapa pendengar khusus, seperti berikut:

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

Tetapkan beberapa pendengar khusus:

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

Dan fungsi 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 kerja .

Jonatas Walker
sumber
Ini bekerja dengan baik! Maaf atas persetujuan yang terlambat. Dua tahun lalu saya tidak benar-benar memahaminya dan menemukan solusi saya sendiri - yang ternyata tidak dapat diandalkan seperti yang terjadi sekarang.
johjoh
4

Anda dapat melampirkan pendengar ke vectorSource Anda http://openlayers.org/en/v3.7.0/apidoc/ol.source.Vector.html#once

misalnya

vectorSource.once('change',function(e){
    if (vectorSource.getState() === 'ready') {
        vectorSource.getFeatureById("US");
    }
});
Orang
sumber
Ya, itulah yang sudah saya lakukan, tetapi acara tidak akan menyala, jika sumber sudah dimuat sebelumnya. Jadi saya ingin memeriksa apakah sumbernya sudah siap. Jika demikian, kerjakan segera - jika tidak, ikat ke acara perubahan.
johjoh
0

Saya berakhir dengan fungsi berikut, untuk mengeksekusi kode ketika sumber vektor siap:

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

Saya tidak yakin apakah pengujian untuk satu fitur dapat diandalkan, karena mungkin saja, bahwa tidak semua fitur tersedia secara bersamaan.

johjoh
sumber
Ini tidak dapat diandalkan, seperti yang terjadi sekarang. Memeriksa satu fitur, tidak memberi tahu apakah fitur lainnya ada. Lihat jawaban yang diterima. Ini bekerja dengan baik untuk saya.
johjoh