2

GeoExt、OpenLayers を使用して Web アプリケーションを開発しており、独自の GeoServer を使用してさまざまなマップを提供しています。それでも、必要に応じてユーザーが他の WMS を追加できるようにして、必要なすべてのレイヤーを操作できるようにしたいと考えています。

したがって、GetFeatureInfo リクエストに関する私の問題。現在、geoext のマップ パネルにツールバー ボタンが追加されています。

new GeoExt.Action({
            iconCls: "feature",
            map: map,
            toggleGroup: "tools",
            tooltip: "Feature",
            control: featureControl             
        })

その制御属性は

var featureControl = new OpenLayers.Control.WMSGetFeatureInfo({
            queryVisible: true,
            drillDown: true,
            infoFormat:"application/vnd.ogc.gml"
        });

また、応答を受け取ったら本当にやりたいことを実行するイベント リスナーも定義しましたが、ここでは関係ありません。私の問題は次のとおりです。

2 つ以上の可視レイヤーがあり、そのうちの少なくとも 1 つが異なるソースからのものであるポイントをユーザーがクリックすることを考慮すると、OpenLayers は異なるソースごとに 1 つの AJAX 要求を実行する必要があり、OpenLayers 自身のドキュメントから、

GetFeatureInfo 応答を受信したときにトリガーされます。イベント オブジェクトには、応答の本文 (文字列) を持つ text プロパティ、解析された機能の配列を持つ features プロパティ、要求をトリガーしたマウス クリックまたはホバー イベントの位置を持つ xy プロパティ、および request プロパティがあります。リクエスト自体で。drillDown が true に設定され、すべてのレイヤーからフィーチャ情報を収集するために複数のリクエストが発行された場合、テキストとリクエストには、最後のリクエストのレスポンス ボディとリクエスト オブジェクトのみが含まれます。

だから、ええ、明らかにすぐにはうまくいきません。デバッガーを見ると、異なるソースから 2 つのレイヤーを指定すると、実際にはリクエストを処理します。最初の応答を待たずに次の応答にジャンプするだけです (明らかに非同期です)。つまり、上記のように最初のリクエストを実行し、それが完了して応答が保存されたら、次のリクエストに進みます。しかし、GeoExt が使用するデータ構造にはまだ慣れていません。

不足している API (GeoExt または OpenLayers) オプション/メソッドはありますか? 良い回避策はありますか?

読んでくれてありがとう :-)

PS: 説明不足で申し訳ありません。英語は私の母国語ではありません。上記の何かが十分に明確でない場合はお知らせください:)

4

3 に答える 3

4

このコントロールが非同期モードでリクエストを行うのは正しいことですが、これは問題ありません。本当の問題は、コントロールがリクエストを処理してイベントをトリガーするときです」 getfeatureinfo" だから、私はこのコントロールの 2 つのメソッドを変更し、それが動作します!、これを行うには、最初にコントロールを宣言し、次にサベージ モードでメソッドを変更しました。コードは次のとおりです。

    getInfo = new OpenLayers.Control.WMSGetFeatureInfo({ drillDown:true , queryVisible: true , maxFeatures:100 });
  //then i declare a variable that help me to handle more than 1 request.....
 getInfo.responses  = [];
 getInfo.handleResponse=function(xy, request) {        var doc = request.responseXML;
    if(!doc || !doc.documentElement) {   doc = request.responseText; }
    var features = this.format.read(doc);
    if (this.drillDown === false) {
        this.triggerGetFeatureInfo(request, xy, features);
    } else {
        this._requestCount++;
        this._features = (this._features || []).concat(features);
        if( this._numRequests > 1){
                          //if the num of RQ, (I mean more than 1 resource ), i put the Request in array, this is for maybe in a future i could be need other properties or methods from RQ, i dont know.
            this.responses.push(request);}
        else{
            this.responses = request;}
        if (this._requestCount === this._numRequests) {
            //here i change the code....
            //this.triggerGetFeatureInfo(request, xy, this._features.concat());
            this.triggerGetFeatureInfo(this.responses, xy, this._features.concat());
            delete this._features;
            delete this._requestCount;
            delete this._numRequests;
            // I Adding this when the all info is done 4 reboot
            this.responses=[];
        }
    }
}

 getInfo.triggerGetFeatureInfo= function( request , xy , features) {
//finally i added this code for get all request.responseText's
if( isArray( request ) ){
    text_rq = '';
    for(i in request ){
        text_rq += request[i].responseText;

        }
    }
else{
    text_rq = request.responseText;

    }

    this.events.triggerEvent("getfeatureinfo", {
       //text: request.responseText,
       text : text_rq,
        features: features,
        request: request,
        xy: xy
    });

    // Reset the cursor.
    OpenLayers.Element.removeClass(this.map.viewPortDiv, "olCursorWait");}

ありがとう、あなたは私の問題を発見する方法を教えてくれました。これが私が解決した方法です。これが他の誰かに役立つことを願っています。

于 2013-03-07T01:08:59.377 に答える
1

sahekaさんの答えはほぼ完璧でした!おめでとうございます。ありがとうございます。私は同じ問題を抱えていましたが、最終的に解決することができました。

あなたのコードで何を変更しますか:

  • isArray() が機能しない場合は、次のように変更します: getInfo.triggerGetFeatureInfo() の最初の行で if(request instanceof Array) {...}
  • ポップアップで結果を表示するには、次の方法があります。

私のコード:

getInfo.addPopup = function(map, text, xy) {
    if(map.popups.length > 0) {
        map.removePopup(map.popups[0]);
    }
    var popup = new OpenLayers.Popup.FramedCloud(
        "anything",
        map.getLonLatFromPixel(xy),
        null,
        text,
        null,
        true
    );
    map.addPopup(popup);
}

getInfo.triggerGetFeatureInfo() 関数で、最後の行の後に次を追加します。

this.addPopup(map, text_rq, xy);
于 2013-12-19T14:42:15.653 に答える
0

GetFeatureInfo リクエストは、JavaScript Ajax 呼び出しとして外部サーバーに送信されます。そのため、セキュリティ上の理由からリクエストがブロックされる可能性があります。独自のドメインのプロキシを使用して、リクエストを外部サーバーに送信する必要があります。

次に、OpenLayers.ProxyHost を適切なパスに設定して、openlayers でこのプロキシを構成します。例えば:

OpenLayers.ProxyHost = "/proxy_script";

背景情報 については、 http://trac.osgeo.org/openlayers/wiki/FrequentlyAskedQuestions#ProxyHostを参照してください。

于 2012-12-26T11:11:27.770 に答える