Archive

Tag Archives: HTTP-POST

There is a new layer class in OpenLayers API: OpenLayers.Layer.WMS.Post [1]. – Great work!

While the “normal” OpenLayers.Layer.WMS class requests maps via HTTP GET, this new class sends the request via HTTP POST. This way, we can now send big client-side created SLD files in our GetMap requests that used to exceed size limits of GET.

This code snippet shows the basic use of OpenLayers.Layer.WMS.Post with a client-side created SLD. You’ll need at least OpenLayers 2.9 to test this on your server. (A full example can be found at http://www.openlayers.org/dev/examples/wms-long-url.html)

var sld = 'define your SLD here';

wms = new OpenLayers.Layer.WMS.Post(
  "name",
  "http://localhost:8080/geoserver/wms",
  {
    'layers': 'myNs:layername',
    format: 'image/jpeg',
    sld_body: sld
  },
  {
    unsupportedBrowsers: []
  }
);

Setting unsupportedBrowsers to an empty list is important! This list by default contains [“mozilla”, “firefox”, “opera”]. These browsers support long GET requests so the developers argued that these browsers wouldn’t need to use POST. Well, turns out that they do ;)

I performed a small stress test using an SLD with approximately 1,000 rules being applied on a big city road network. While my browser would willingly send a GET request of that size, Apache doesn’t want to accept it. So, I tried the POST way and it turns out that it really works! (But it’s slow, very slow …)

Thanks to the developers for yet another great feature!

[1] http://trac.openlayers.org/ticket/2224

Usually, I use CQL filter statements to dynamically filter features in a Geoserver WMS. These CQL filters can be added easily to the URL and Geoserver responds accordingly. There’s just one problem: There is a size limit for URLs and (very!) long filter statements won’t fit in. (And I’m not talking about the limit imposed by IE, but the more serious one in Apache.) This makes it necessary to switch from HTTP GET to POST. An easy way to send POST requests is using curl:

curl --data-binary @getMap.xml -H "Content-Type: text/xml" -o map.png "http://localhost:8080/geoserver/wms/GetMap"

I found that it’s important to use –data-binary to avoid that the text in getMap.xml is interpreted in any way. The “@” tells curl that a filename follows. Furthermore it’s necessary to specify the Content-Type. This results in the PNG map being stored in the current directory. My getMap.xml looks like follows:

<?xml version="1.0" encoding="UTF-8"?>
<ogc:GetMap
xmlns:ogc="http://www.opengis.net/ows"
xmlns:gml="http://www.opengis.net/gml"
version="1.1.1" service="WMS">

<StyledLayerDescriptor version="1.0.0">
<NamedLayer>
 <Name>myNs:roads</Name>
 <NamedStyle>
  <Name>simple_roads</Name>
 </NamedStyle>
</NamedLayer>
</StyledLayerDescriptor>

<BoundingBox srsName="http://www.opengis.net/gml/srs/epsg.xml#31287">
<gml:coord>
<gml:X>621005.1594799113</gml:X>
<gml:Y>471313.0306986364</gml:Y>
</gml:coord>
<gml:coord>
<gml:X>635174.7245025429</gml:X>
<gml:Y>484404.226939031</gml:Y>
</gml:coord>
</BoundingBox>

<Output>
 <Format>image/png</Format>
 <Size>
 <Width>600</Width>
 <Height>320</Height>
 </Size>
</Output>

<Exceptions>application/vnd.ogc.se+xml</Exceptions>

</ogc:GetMap>

It’s also pretty straightforward to add a filter to the NamedLayer element. Basically it can be copied from any SLD you have at hand.

%d bloggers like this: