OpenLayers 3:ベクターソースの準備ができているかどうかを確認する方法


8

ol.source.getState()信頼できないようです。ベクターソースで呼び出すと、準備ができていますが、機能はまだ利用できません。コードは次のようになります。

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

ベクトルソースの準備ができているかどうかを確認する他の方法はありますか?


この機能IDが存在するかどうかを確認しましたか?
Jonatas Walker、2015

@JonatasWalker、はい、存在します。
johjoh 2015

回答:


8

次のように、独自のローダー関数を提供し、いくつかのカスタムリスナーを設定できます。

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

いくつかのカスタムリスナーを設定します。

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

そして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);
};

作業デモ


これはうまくいきます!承認が遅れてすみません。2年前、私は実際にそれを理解していなかったため、自分の解決策を見つけました。
johjoh 2017

3

リスナーをvectorSource http://openlayers.org/en/v3.7.0/apidoc/ol.source.Vector.html#onceにアタッチできます

例えば

vectorSource.once('change',function(e){
    if (vectorSource.getState() === 'ready') {
        vectorSource.getFeatureById("US");
    }
});

はい、それは私がすでに行っていることですが、ソースが既にロードされている場合、イベントは発生しません。そこで、ソースが準備できているかどうかを確認したいと思いました。その場合は、すぐに作業してください。そうでない場合は、変更イベントにバインドしてください。
johjoh

0

ベクトルソースの準備ができたときにコードを実行するために、次の関数を作成しました。

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

単一の機能のテストが信頼できるかどうか、確かかもしれませんが、すべての機能が同時に利用できるわけではありません。


現在判明しているため、これは信頼できません。1つの機能をチェックしても、他の機能があるかどうかはわかりません。受け入れられた答えを見てください。それは私にはうまくいきます。
johjoh 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.