I am loading layers in OpenLayers, and dynamically building a protocol for "identifying" elements in that layer when the user clicks the map, and that layer was the selected "Identify" layer. This is pretty standard in many applications.

Now one of the "layers" I am loading is actually defined as a Layer Group in GeoServer.

I traced the HTTP request made by OpenLayers to a WFS service at GeoServer, and here is the POST payload:

 <wfs:GetFeature xmlns:wfs="http://www.opengis.net/wfs" service="WFS" version="1.1.0" maxFeatures="2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
    <wfs:Query typeName="MYWORKGROUP:MyLayerGroup" srsName="EPSG:900913" xmlns:MYWORKGROUP="http://www.myurl.com">
                <gml:Envelope xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:900913">
                    <gml:lowerCorner>-8081435.512129 5125105.8658893</gml:lowerCorner>
                    <gml:upperCorner>-8081411.6255577 5125129.7524606</gml:upperCorner>

Here is the response:

<ows:ExceptionReport xmlns:ows="http://www.opengis.net/ows" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/ows https://mygeoserver:8080/schemas/ows/1.0.0/owsExceptionReport.xsd">
  <ows:Exception exceptionCode="InvalidParameterValue" locator="typeName">
    <ows:ExceptionText>Could not locate {http://www.myurl.com}MyLayerGroup in catalog.</ows:ExceptionText>

Perhaps I just can't do this, and need to configure the actual layer(s) to query for identifying items completely separately from the list of layers to make available for viewing, as some of the viewable layers will be Layer Groups? That's a pain - if someone changes the layer(s) in the group, I would need to change my configuration for including that layer.

What made me think I could do this was the fact that you can "preview" a LayerGroup in GeoServer's UI, and click on that group, and it returns items under the mouse click from every layer in the layer group. But that query is a WMS GetFeatureInfo query... Not sure how to put THAT into a protocol for an OpenLayers featureControl...

Here is the URL I traced when previewing:

  • perhaps I just can't do this, Correct. Layers and layer groups are there to help you with the rendering of images as part of a WMS, the same concept doesn't exist with a WFS, which doesn't deal with layers at all. – nmtoken Jan 22 '17 at 18:13
  • Well, if I really want to "automatically" use the correct layer within the group, I suppose I could use REST calls to Geoserver to discover what layers are in that group. And if I cannot tell which by the name of the layer, then make more REST calls to see which of these have the attribute(s) I'm querying on. Or just query them all, those without that attribute will simply return an error... More trouble than it is worth for me right now, though, but an interesting option... – Brian B Jan 23 '17 at 13:46

You are correct- you first need to know which layers ('sublayers') exist in the group layer. If this is your own server and you already know what the sublayers are, you can skip to the end of this howto. Otherwise, to find them programmatically, ajax call a url constructed like this:

http://<your server and/or port>/geoserver/<workspace>/wms?service=WMS&version=1.1.1&request=DescribeLayer&layers=<workspace>:<group layer>

The above returns an XML document that can be iteratively parsed for 'typeName'. (Follow this link on javascript/jquery suggestions for how to parse the xml).

At this point, you'll have (presumably) two or more typeNames, each being a 'sub layer' of the group layer. Excellent.

My approach is to set up asynchronous javascript functions with callbacks that on completion pass these typeNames to another ajax call with a typical WFS GetFeature url constructed with the multiple typeNames separated by commas, like this:

http://<your server and/or port>/geoserver/<workspace>/wms?service=WFS&version=1.0.0&request=GetFeature&typeName=<typeName 1>,<typeName 2 etc>&outputFormat=application%2Fjson&maxFeatures=50&cql_filter=<.... and so on>

In the example provided, this returns a json formatted string with whatever it is you are looking for.

*Note: Keep in mind that version numbers, geoserver url's, workspace locations etc. will all be unique to your or a remote setup... I've never been able to cruise anyone's (public) server without a little trial and error.

| improve this answer | |

Your Answer

