如何使用Vuelayers与由GeoServer提供的WMS瓦片图层进行交互?

8
我正在使用Vuelayers库开发一个Web映射应用程序,它是一组Web地图Vue组件,拥有OpenLayers的强大功能。 我在模板中有以下代码:
<vl-map @singleclick="hideOverlay" @postcompose="onMapPostCompose"
 :load-tiles-while-animating="true" ref="map"
:load-tiles-while-interacting="true" data-projection="EPSG:4326"
style="height: 900px" @mounted="onMapMounted">
 ....

  <component v-for="layer in layers" :ref="layer.id" overlay
    :is="layer.cmp"
    :key="layer.id" v-bind="layer">
        <component :is="layer.source.cmp" v-if="layer.visible" v-bind="layer.source">
        </component>
    </component>
     ....
</vl-map>


在数据对象中,我有以下属性:
     layers: [

            {
                id: 'sections',
                title: 'Sections',
                cmp: 'vl-layer-tile',
                visible: true,

                source: {
                    cmp: 'vl-source-wms',
                    url: 'http://localhost:8080/geoserver/sager/wms',
                    layers: 'sections',
                    tiled: true,
                    format: 'image/png',
                    serverType: 'geoserver',
                },
            },
     ....
    ]

当我点击图层时,如何获取其属性?需要注意的是,vl-tile-layer没有提到@click事件,具体请参见这里

1
你不应该使用 v-if 和 v-for 吗? - Andrew1325
1
@Andrew1325不是问题,这个可以正常工作,但我找不到一种与WMS图层交互的方法。 - Boussadjra Brahim
1
是的,我知道,只是说一下。这是一个棘手的问题。 - Andrew1325
1
你看过这个了吗? - Andrew1325
2
我建议使用 Codesandbox 搭建一个包含依赖项和简单示例以重现问题的环境。 - Jess
显示剩余2条评论
1个回答

5
只需将点击事件处理程序放在顶层地图组件上,如下所示:
<vl-map @click="mapClick" @singleclick="hideOverlay" @postcompose="onMapPostCompose"
 :load-tiles-while-animating="true" ref="map"
:load-tiles-while-interacting="true" data-projection="EPSG:4326"
style="height: 900px" @mounted="onMapMounted">

</vl-map>

然后在点击事件中使用forEachLayerAtPixel函数,该函数对于显示在屏幕像素上的每个图层进行操作,并给出ol.Layer.Layer对象,您可以调用getProperties()方法获取该对象的属性:

 methods: {
  mapClick: function(evt){
    evt.map.forEachLayerAtPixel(
        evt.pixel,
        function(layer){ layer.getProperties()},
        function(layer){/*filter layers you want to get property data on*/})
  }
}

上述方法仅在服务器上设置了CORS并且您可以在vue-layers在后台使用的OpenLayers图层上设置crossOrigin设置时才能生效。上述方法更好,但如果出现错误:

,请尝试以下方法:
"SecurityError: Failed to execute 'getImageData' on 
'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data

那么你可以使用一个更通用的函数,比如

evt.map.getLayers().item(0)

or

evt.map.getLayers.forEach(
    function(layer){
        layerProps = layer.getProperties()
        if(layerProps.id === "the one you want")
        {
            // You will have to implement your own intersection logic here
            // to see if the click point intersected with the layer.
        }
})

1
谢谢你的回答,但是当我尝试时出现了这个错误v-on处理程序中的错误:“SecurityError:在CanvasRenderingContext2D上执行'getImageData'失败:画布已被跨源数据污染 - Boussadjra Brahim
2
是的,我对Open Layers不是很熟悉,但那听起来像是一个画布问题,不容易解决。你可以查找该错误并了解它是画布元素的安全特性,只能通过服务器端头文件绕过或使用更通用的函数来解决。我会编辑我的答案以反映这一点。 - Ryan
1
历史记录在此答案的修订历史中。也许只需更改答案以反映最新版本?(如果需要,可以在此处放置更改说明的评论。) - Peter Mortensen
第一个版本可以使用且是首选,但需要正确设置服务器的CORS。此外,vue-layers的文档不完整,也没有指定一种在支持的OpenLayers图层中设置crossOrigin设置的方法。 - Ryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接