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 个以上可见层并且其中至少有一个来自不同来源的点,OpenLayers 将不得不为每个不同来源执行一个 AJAX 请求,并且根据 OpenLayers 自己的文档,

收到 GetFeatureInfo 响应时触发。事件对象有一个带有响应正文的文本属性(字符串),一个带有解析特征数组的特性属性,一个带有触发请求的鼠标单击或悬停事件位置的 xy 属性,以及一个请求属性与请求本身。如果 DrillDown 设置为 true 并且发出了多个请求以从所有层收集要素信息,则文本和请求将仅包含最后一个请求的响应正文和请求对象。

所以,是的,它显然不会马上那样工作。看一下调试器,我可以清楚地看到,从不同的来源给出两个层,它实际上执行了请求,只是它不等待第一个的响应并跳转到下一个(显然,是异步的)。我已经考虑过一个接一个地处理请求,这意味着按照上述方式执行第一个请求,一旦完成并保存响应,就可以进行下一个请求。但我仍然习惯了 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 回答