我正在尝试在Google地图上呈现WMS图层,并且除了getfeatureinfo事件之外它的工作正常。当我打开Geoserver并尝试点击WMS特色时,我可以获得功能信息。但在我的页面中我可以看到空弹出窗口。我认为问题在于Google Maps Projection。
代码:
function init(){
var gmap = new OpenLayers.Layer.Google("Google Streets", {
visibility: false});
var options = {
controls : [],
units : "m",
numZoomLevels : 22,
maxResolution : 156543.0339,
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
maxExtent : new OpenLayers.Bounds(-20037508.34, -20037508.34,
20037508.34, 20037508.34)
};
var map = new OpenLayers.Map('map', options);
var layer1 = new OpenLayers.Layer.WMS("Layer1 - Tiled",
"http://localhost:8090/geoserver/Layers/wms", {
layers : "Layer1",
transparent : "true",
format : "image/png",
srs : 'EPSG:4326',
zoomOffset : 3,
}, {
isBaseLayer : false
});
map.addLayer(gmap);
map.addLayer(layer1);
info = new OpenLayers.Control.WMSGetFeatureInfo({
url: 'http://localhost:8090/geoserver/Layers/wms',
title: 'Identify features by clicking',
layers: [layer1],
infoFormat: 'text/html',
queryVisible: true,
eventListeners: {
getfeatureinfo: function(event) {
map.addPopup(new OpenLayers.Popup.FramedCloud(
"chicken",
map.getLonLatFromPixel(event.xy),
null,
event.text,
null,
true
));
}
}
});
map.addControl(info);
info.activate();
map.setCenter(new OpenLayers.LonLat(-104.949, 40.924).transform(
new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()),5);
map.addControl(new OpenLayers.Control.Navigation());
}
<body onload="init()">
<div style="visibility: visible; height: 100%;" id="map"></div>
</body>
在google地图(EPSG:900913)和WMS图层(EPSG:4326)的情况下,有没有办法获得getfeatureinfo?我需要更改我的代码吗?请分享您宝贵的想法。
帮助将不胜感激:)
答案 0 :(得分:3)
function fromLatLngToPoint(latLng, map) {
var topRight = map.getProjection().fromLatLngToPoint(map.getBounds().getNorthEast());
var bottomLeft = map.getProjection().fromLatLngToPoint(map.getBounds().getSouthWest());
var scale = Math.pow(2, map.getZoom());
var worldPoint = map.getProjection().fromLatLngToPoint(latLng);
return new google.maps.Point((worldPoint.x - bottomLeft.x) * scale, (worldPoint.y - topRight.y) * scale);
}
function getRadius(zoom) {
var radius_px = 0.40/2
var constMetersDegress = 1000; // TODO Verifiy
//zoom <-> m/px = http://timwhitlock.info/blog/2010/04/google-maps-zoom-scales/
var scaled_zooms = {
22: 0.02,
21: 0.04,
20: 0.09,
19: 0.19,
18: 0.37,
17: 0.74,
16: 1.48,
15: 3,
14: 6,
13: 12,
12: 24,
11: 48,
10: 95,
9: 190,
8: 378,
7: 752,
6: 1485,
5: 2909,
4: 5540,
3: 10064,
2: 16355,
1: 21282,
0: 30000
}
var radius_meters = radius_px * scaled_zooms[zoom];
var radius_degrees = radius_meters / constMetersDegress;
return radius_degrees;
}
function getFeatureInfoURL(latLng){
var lat = parseFloat(latLng.lat());
var lng = parseFloat(latLng.lng());
//console.info('------------------------------')
var radius_degrees = getRadius(map.getZoom());
var buffer_sw_y_dd = lat-radius_degrees
var buffer_sw_x_dd = lng-radius_degrees
var buffer_ne_y_dd = lat+radius_degrees
var buffer_ne_x_dd = lng+radius_degrees
//console.info('bbox dd',buffer_sw_x_dd+','+buffer_sw_y_dd+','+buffer_ne_x_dd+','+buffer_ne_y_dd)
var buffer_sw_dd = new google.maps.LatLng( buffer_sw_y_dd, buffer_sw_x_dd )//decimal degrees
var buffer_ne_dd = new google.maps.LatLng( buffer_ne_y_dd, buffer_ne_x_dd )//decimal degrees
var buffer_sw_px = fromLatLngToPoint(buffer_sw_dd, map);//pixels
var buffer_ne_px = fromLatLngToPoint(buffer_ne_dd, map);//pixels
//console.info('buffer_sw_px',buffer_sw_px,'buffer_ne_px',buffer_ne_px)
var buffer_width_px = ( Math.abs( buffer_ne_px.x - buffer_sw_px.x ) ).toFixed(0);
var buffer_height_px = ( Math.abs( buffer_ne_px.y - buffer_sw_px.y ) ).toFixed(0);
//console.info('buffer_width_px',buffer_width_px, 'buffer_height_px',buffer_height_px)
var center_x_px = (buffer_width_px / 2).toFixed(0);
var center_y_px = (buffer_height_px / 2).toFixed(0);
//console.info('center_x_px',center_x_px,'center_y_px',center_y_px)
//console.info('------------------------------')
var url = this.baseUrl;
url +='&SERVICE=WMS';
url +='&VERSION=1.1.0';
url +='&REQUEST=GetFeatureInfo';
url +='&TRANSPARENT=true';
url +='&QUERY_LAYERS='+layerName;
url +='&STYLES';
url +='&LAYERS='+layerName;
url +='&INFO_FORMAT=text/html';
url +='&SRS=EPSG:4326';
url +='&FEATURE_COUNT=10';
url +='&WIDTH='+buffer_width_px;
url +='&HEIGHT='+buffer_height_px;
url +='&Y='+center_y_px;
url +='&X='+center_x_px;
url +='&BBOX='+buffer_sw_x_dd+','+buffer_sw_y_dd+','+buffer_ne_x_dd+','+buffer_ne_y_dd;
return url;
};
希望这会有所帮助
答案 1 :(得分:2)
我刚刚使用指向geoserver演示网站的确切代码运行了一个演示,它运行得很好。下面的示例显示了国家/地区边界等,因此只需前往美国/加拿大边境点击即可。我怀疑你的问题是GetFeatureInfo不能保证总是返回一些东西。可以进行该调用,WMS服务器返回GetFeatureInfo不可用于该层的异常。
另一个可能的问题是你要求GetFeatureInfo以text / html格式返回信息格式。如果您还没有在服务器上定义HTML模板,它也可能会返回异常,尽管我不确定这里会出现什么错误。您应该切换到最简单的默认选项text / plain。它看起来不会很漂亮,但是当你想出其他所有东西时,它会删除一个可能会破坏的地方。
我建议您在Chrome中尝试此代码示例,以便您可以使用调试工具并检查网络选项卡,并查看向后和向前流动的WMS请求的内容。
最后,如果你看到异常回来,你可以通过要求在JSON中返回异常来防御性地编码,这样你就有可能捕获错误。
祝你好运!<html>
<head>
<script src="lib/OpenLayers.js"></script>
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
<script type="text/javascript">
function init() {
var gmap = new OpenLayers.Layer.Google("Google Streets", {
visibility: false});
var options = {
controls : [],
units : "m",
numZoomLevels : 22,
maxResolution : 156543.0339,
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
maxExtent : new OpenLayers.Bounds(-20037508.34, -20037508.34,
20037508.34, 20037508.34)
};
var map = new OpenLayers.Map('map', options);
var layer1 = new OpenLayers.Layer.WMS("Layer1 - Tiled",
"http://demo.opengeo.org/geoserver/ows?", {
layers : "osm:admin_01234",
transparent : "true",
format : "image/png",
srs : 'EPSG:4326',
zoomOffset : 3,
}, {
isBaseLayer : false
});
map.addLayer(gmap);
map.addLayer(layer1);
info = new OpenLayers.Control.WMSGetFeatureInfo({
url: 'http://demo.opengeo.org/geoserver/ows?',
title: 'Identify features by clicking',
layers: [layer1],
infoFormat: 'text/html',
queryVisible: true,
eventListeners: {
getfeatureinfo: function(event) {
map.addPopup(new OpenLayers.Popup.FramedCloud(
"chicken",
map.getLonLatFromPixel(event.xy),
null,
event.text,
null,
true
));
}
}
});
map.addControl(info);
info.activate();
map.setCenter(new OpenLayers.LonLat(-104.949, 40.924).transform(
new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()),5);
map.addControl(new OpenLayers.Control.Navigation());
}
</script>
<body onload="init()">
<div style="visibility: visible; height: 100%;" id="map"></div>
</body>
答案 2 :(得分:0)
我没有可用的测试环境(你能设置一个合适的jsfiddle,非localhost wms吗?),但是你可能正在浏览器上使用XSS过滤器。
看这篇文章: http://cggis.wordpress.com/2011/05/19/getfeatureinfo/
使用“--disable-web-security”标志启动Chrome应该是一个快速测试,以排除这种可能性。