如何使用 Vuelayers 与 GeoServer 提供的 WMS 切片图层进行交互?
How do I interact with WMS tile layer served by GeoServer using Vuelayers?
我正在使用 Vuelayers
库开发一个网络地图应用程序,该库是 具有 OpenLayers 强大功能的网络地图 Vue 组件。
我的模板中有以下代码:
<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
事件 here.
只需将点击处理程序放在顶级地图组件上,如下所示:
<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>
然后在点击事件中使用可以调用 getProperties() 的 forEachLayerAtPixel function which operates on each layer that is displaying at that screen pixel and gives you the ol.Layer.Layer 对象:
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.
}
})
我正在使用 Vuelayers
库开发一个网络地图应用程序,该库是 具有 OpenLayers 强大功能的网络地图 Vue 组件。
我的模板中有以下代码:
<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
事件 here.
只需将点击处理程序放在顶级地图组件上,如下所示:
<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>
然后在点击事件中使用可以调用 getProperties() 的 forEachLayerAtPixel function which operates on each layer that is displaying at that screen pixel and gives you the ol.Layer.Layer 对象:
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.
}
})