Openlayers WMS getfeatureinfo在Google Maps上发布

时间:2014-05-25 16:35:45

标签: javascript google-maps google-maps-api-3 openlayers geoserver

我正在尝试在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?我需要更改我的代码吗?请分享您宝贵的想法。

帮助将不胜感激:)

3 个答案:

答案 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&amp;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应该是一个快速测试,以排除这种可能性。