Tuesday, April 14, 2009

WMS Tiling Clients

For projects relying on open source software and using WMS services for their map applications perhaps the most obvious choice for a client application is to write something using the OpenLayers API. This is a very extensive javascript API and is used to demonstrate the open source OGC compliant servers MapServer and GeoServer. Its straight forward to construct a map and then to overlay multiple layers using WMS services.

The screenshot above shows a layer of 0.1 degree cell densities representing data from Australian National Herbarium rendered using GeoServer layered on top of the Google satellite base layer, all pulled together using OpenLayers.

Running this locally the map was rendered by OpenLayers rather quickly. Running this on an externally hosted server I began to notice curious loading of tiles by OpenLayers. So I did a stripped down comparison of the same functionality using the Google maps API. Rendering the cell density tiles from a WMS service in Google maps was done using a javascript function written by John Deck - available here.

The performance improvement with Google maps was immediately obvious. Using the Firefox YSlow plugin we see:



OpenLayersGoogle Maps API




So the main thing of interest here is the number of tiles loaded by OpenLayers compared to Google maps (91 vs 50 - although oddly the total size of the images loaded is roughly equivalent, and the tile size for both seems to be 256x256 pixels). Increasing the size of the tile for OpenLayers does reduce the number of tiles requested (I tested with 512x512 and 1024x1024) but this has little effect on performance in openlayers.

So the performance difference between Google Maps and OpenLayers could be accounted for by any combination of the following:
  • Incorrect use of the API (test for OpenLayers is here) and we are missing configuration to reduce tile loading in openlayers
  • The tile loading algorithm for Google maps is more efficient in only loading the required tiles for selected view areas
  • Openlayers is preloading more images to speed up panning. This would be good, but OpenLayers doesnt seem to prioritise the loading of currently viewed tiles.
The source for the test for OpenLayers is here, and for Google maps here.

2 comments:

Tim Carpenter said...

The OpenLayers.Layer.Grid class has a buffer property that "specifies the number of extra rows and colums of tiles on each side which will surround the minimum grid tiles to cover the map".

http://dev.openlayers.org/releases/OpenLayers-2.7/doc/apidocs/files/OpenLayers/Layer/Grid-js.html#OpenLayers.Layer.Grid.bufferIn 2.7 this seems to default to 2, which, depending on the size of the map window, could be quite a few tiles, (at least 35 by my rough calculations for your map size).

Would be interesting if you set this to 0 or 1 for your WMS layer and ran the same test.

Dave Martin said...

Thanks a lot Tim.

It does indeed make a difference. I think I originally tried passing the "buffer" value through as a "param" instead of an "option". Passing through as an option has the desired effect of reducing the number of loaded tiles (from 91 -> 48 images).

e.g.

var cellLayer = new OpenLayers.Layer.WMS("Animalia 1 degree cells",
"http://maps.ala.org.au/wms?",
{params...},
{buffer:0});

Thanks again!