OpenLayers:多层弹出问题

时间:2013-12-12 05:04:07

标签: popup openlayers layer

我实际上遇到了一个迄今为止我无法解决的大问题。这是我的问题。我实际上有一张地图,我正在显示标记(WMSGetFeatureInfo),具体取决于我想要显示或隐藏的某些类别。

但事实上,我实际上将这些标记作为 * .map 文件,这实际上是一个包含所有标记的PNG文件。

当我点击标记时,我将获得点击的位置,然后添加一个弹出窗口。但是我在地图上显示的图层越多,弹出窗口就越远离相关标记。

这里有一些代码:

    var layer = new OpenLayers.Layer.WMS(
        category.label,
        "/mapserv?Map=" + category.url,
        {
            layers  : category.layer,
            format  : 'image/png',
            version : '1.3.0',
            srs     : 'ESPG:3163'
        },
        {
            isBaseLayer : false,
            singleTile  : true,
            visibility  : visibility,
        }
    );

    var info = new OpenLayers.Control.WMSGetFeatureInfo({
        title          : 'get details by clicking',
        layers         : [ layer ],
        infoFormat     : "text/plain",
        queryVisible   : true,
        eventListeners : {
            getfeatureinfo : function( event ){
                document.body.style.cursor = 'auto';

                var getId = function( text ) {
                    result = context.settings.pattern.exec( text );
                    if( result == null ) return;
                    return result[1];
                }

                var id = getId( event.text );

                request = jQuery.ajax({
                    url     : "/cartoweb/FicheTheme",
                    type    : "get",
                    data    : "idGeoEad="+id,
                    success : function(response, textStatus, jqXHR){
                        if (response == null || response['data'] == null) {
                            return;
                        }
                        context.generateAndShowPopup( event.xy, response['data']['metaData'] );
                    }
                });
            },
            beforegetfeatureinfo : function( event ){
                document.body.style.cursor = 'wait';
            },
            nogetfeatureinfo : function( event ){
                document.body.style.cursor = 'auto';
            }
        }
    });

    this.map.addControl( info );
    info.activate();


generateAndShowPopup : function( latlong, text ) {
    var lonlatfrompx = this.map.getLonLatFromViewPortPx( latlong );
    var anchor       = {
        'size'      : new OpenLayers.Size(0,0), 
        'offset'    : new OpenLayers.Pixel(-36, 6), 
        'keepInMap' : true
    };

    // Hide by default popup actually open
    if(this.popup !== undefined) {
        this.popup.hide();
    }

    // Create a new popup
    this.popup = new OpenLayers.Popup.Anchored(
        "chicken",
        lonlatfrompx,
        new OpenLayers.Size( 2000, 2000 ),
        '<div class="popupTail"></div><div class="popupContent">' + text + '</div>',
        anchor,
        false, 
        function(){}
    );

    // Popup settings
    this.popup.setBackgroundColor( 'transparent' );
    this.popup.panMapIfOutOfView         = true;
    this.popup.calculateRelativePosition = function () { return 'tr'; }

    // Add it on the map
    this.map.addPopup( this.popup );

    var that = this;
    setTimeout(function(){
        that.popup.updateSize();
    }, 50);

    this.map.setCenter( lonlatfrompx );
}

不确定我是否做错了,但如果有人已经遇到同样的问题,那么知道我做错了什么会非常有帮助。

非常感谢

修改
好的,所以我试图在图层上重新投影latlong,但它仍然无法正常工作。但是,我正在取得进展:

// Layer is the layer associated to each WMSGetFeatureInfo
// this.layer is the base layer used to display the map
lonlatfrompx.transform( layer.projection, this.layer.projection );
this.map.setCenter( lonlatfrompx );

编辑1
好的,我正在取得进展。我想我知道问题的来源,但我仍然没有看到/知道我将如何解决它(尚未)。

当对info变量进行转换时,我正在进行ajax调用,其中会在单击时显示弹出窗口。问题是我添加的层越多,这个ajax请求尝试获取信息的次数就越多。

让我们说,我在地图上显示5个不同的层(IT,设计,启动,计算机和桌面)。然后,当我点击标记(WMSGetFeatureInfo)时,它实际上尝试创建一个ajax request * [number of layers visible],然后在某个时刻(有时)更改位置值。

为了解决这个问题,我需要避免这个ajax请求执行多次。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

当我第一次阅读您的帖子时,我误解了您使用OpenLayers.Marker的“标记”,我认为您最好还是称之为“标记”WMSGetFeatureInfo。读者更容易遵循它:)

我个人认为你得到的问题是你的地图投影,当你定义参数“lonlatfrompx”时你的图层投影是“ESPG:3163”,你没有重新投影lon / lat(EPSG:4326)到“ ESPG:3163" 。所以弹出窗口的lon / lat会是错误的......

<强>更新

通过阅读“编辑1”我只是注意到你编写“var info = new OpenLayers.Control.WMSGetFeatureInfo”函数的方式非常奇怪,为什么需要在WMSGetFeatureInfo中添加ajax调用?通常的方法是使用“url”参数来查询wms而不是使用ajax调用。例如:

info = new OpenLayers.Control.WMSGetFeatureInfo({
        url: 'http://demo.opengeo.org/geoserver/wms', 
        title: 'Identify features by clicking',
        queryVisible: true,
        layers: [layer],
        eventListeners: {
            getfeatureinfo: function(event) {
                // add popup here
                map.addPopup(new OpenLayers.Popup.FramedCloud(
                    "chicken", 
                    map.getLonLatFromPixel(event.xy),
                    null,
                    event.text,
                    null,
                    true
                ));
            },
            beforegetfeatureinfo: function(event) {
            ......
            },
            nogetfeatureinfo: function(event) {
            ......
            }
            ......
        }
    });

更新2

第一:

是的,如果包含多个源(层),WMSGetFeatureInfo将向WMS服务器发送多个请求。这就是你的ajax多次调用的原因。

同一地图位置(鼠标点击点)上的所有图层是否具有相同的ID(idGeoEad)?如果他们这样做,有一种快速而肮脏的方式,它只提供一层“层”参数(而不是层数组),那么ajax调用只会触发一次。或者只是不要设置图层和&amp; url参数,它将找到第一个符合条件的图层。

第二:

即使是这种情况,我认为它不应该影响你的弹出位置。因为“event.xy”和“lonlatfrompx”应该始终相同。所以我认为弹出窗口指向远离相关标记仍然是由错误投影引起的。 因此,请仔细检查您的地图投影,地图显示投影和所有图层的投影。另外,请检查地图文件设置中的所有图层投影是否正确?所有图层都使用“EPSG:3163”吗? 在上面的代码中,我注意到一个拼写错误的“srs:'ESPG:3163'”,它应该是EPSG:3163。

如果你使用fire-bug或谷歌开发者工具,请调试或console.log看看“event.xy”和“lonlatfrompx”每次都会得到正确的位置。