WMS GetFeatureInfo;多层,不同来源
Posted
技术标签:
【中文标题】WMS GetFeatureInfo;多层,不同来源【英文标题】:WMS GetFeatureInfo; multiple layers, different sources 【发布时间】:2012-12-17 13:58:45 【问题描述】:我正在使用 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 响应时触发。事件 对象有一个带有响应正文的文本属性(字符串),一个 features 属性与解析的特征数组,一个 xy 属性 与触发鼠标单击或悬停事件的位置 请求,以及请求本身的请求属性。如果向下钻取 设置为 true 并发出多个请求以收集功能 来自所有层、文本和请求的信息将仅包含响应 最后一个请求的主体和请求对象。
所以,是的,它显然不会立即那样工作。看一下调试器,我可以清楚地看到,从不同的来源给出两个层,它实际上执行了请求,只是它不等待第一个的响应并跳转到下一个(显然,是异步的)。我已经考虑过一个接一个地处理请求,这意味着按照上述方式执行第一个请求,一旦完成并保存响应,就可以进行下一个请求。但我还是习惯了 GeoExt 使用的数据结构。
我是否缺少任何 API(无论是 GeoExt 还是 OpenLayers)选项/方法?有什么好的解决方法吗?
感谢阅读:-)
PS:对不起,如果我不够清楚,英语不是我的母语。如果上述内容不够清楚,请告诉我:)
【问题讨论】:
【参考方案1】:我希望这对其他人有所帮助,我意识到:您可以让这个控件以异步模式发出请求,但这没关系,没问题,真正的问题是控件何时处理请求并触发事件“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");
谢谢,你给我带来了一种发现我的问题的方法,这是我解决的方法,我希望这对其他人有帮助。
【讨论】:
对不起我的英语太糟糕了:S 哇,感谢您的详细回答!我会检查它是否也适用于我,如果是,则将您的答案标记为正确:-)【参考方案2】: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);
【讨论】:
【参考方案3】:GetFeatureInfo 请求作为 javascript Ajax 调用发送到外部服务器。因此,出于安全原因,这些请求可能会被阻止。您必须通过您自己域上的代理将请求发送到外部服务器。
然后,通过将 OpenLayers.ProxyHost 设置为正确的路径,在 openlayers 中配置此代理。例如:
OpenLayers.ProxyHost = "/proxy_script";
有关更多背景信息,请参阅http://trac.osgeo.org/openlayers/wiki/FrequentlyAskedQuestions#ProxyHost。
【讨论】:
以上是关于WMS GetFeatureInfo;多层,不同来源的主要内容,如果未能解决你的问题,请参考以下文章
WMS GetFeatureInfo (Tile Layer)——WMS获取要素信息(瓦片图层)
怎样使GeoServer在WMS的GetFeatureInfo请求返回JSON格式数据