Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I interact with WMS tile layer served by GeoServer using Vuelayers?

I'm developing a web mapping application using the Vuelayers library which is Web map Vue components with the power of OpenLayers.

I have the following code in my template:

<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>

And in the data object I have the following property:

     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',
                },
            },
     ....
    ]

So how do I get the layer properties when I click on it? Knowing that vl-tile-layer doesn't have the @click event as mentioned here.

like image 957
Boussadjra Brahim Avatar asked May 26 '19 23:05

Boussadjra Brahim


People also ask

What is GWC in GeoServer?

GeoWebCache (GWC) is a modular tile cache system able to support the most common tile oriented protocols, using any compliant WMS server as a source for tiles, and caching them on disk for speed. GeoWebCache can run either stand-alone as a J2EE web application, or as a GeoServer plugin.


1 Answers

Just put the click handler on the top level map component like so:

<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>

Then in the click event use the forEachLayerAtPixel function which operates on each layer that is displaying at that screen pixel and gives you the ol.Layer.Layer object which you can call getProperties() on:

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

The above will only work if CORS is setup on the server and if you can set the crossOrigin setting on the OpenLayers layer that vue-layers is using behind the scenes. the above method is better but if you get an error stating

"SecurityError: Failed to execute 'getImageData' on 
'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data

Then you can use a more general function like

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.
        }
})
like image 68
Ryan Avatar answered Nov 01 '22 00:11

Ryan