Linfiniti Geo Blog

GIS for Open Source People

Browsing Posts published in July, 2009

Good news if you are a PostGIS fan – the PostGIS team just released version 1.4! See the release announcement for full details…

A tilecache is an application that pre-renders a WMS (web mapping service) to rasters. Pre-rendering is useful to improve server side performance – at the expense of some disk space. The tiles are rendered at different scales and when a client that suppots the WMS Tiling protocol makes a request for an image, the server can simply return the pre-rendered image. Obviously this doesnt work well when you have a lot of dynamically changing data that you are trying to serve up. If your data changes with less frequency, it might still be worth employing the services of a tile caching application, but ‘reseeding’ it on a regular basis. In this article I will look at two popular tile caching applications, TileCache and GeoWebCache.

I have used both GeoServer and MapServer for hosting GeoSpatial data. Both are great products, though I tend to lean towards MapServer since it is simple to setup and configure and uses no resources when not actively servicing requests (when using the cgi build). So I’ll be testing both GeoWebCache and TileCache against a MapServer install on my local development machine. Note that I will only be covering the simplest use case here – both applications support substantially more options than are described here so you should consult their home pages for more details. I used a demo MapServer project which was available on my local server at: http://localhost/cgi-bin/mapserv?map=WORLD_MAP

GeoWebCache

If you are a GeoServer user, you may well be using GeoWebCache without realising it. However, GeoWebCache can also be used independently of GeoServer, which is what we will look at here. The process for setting up GeoWebCache is somewhat similar to setting up GeoServer. In a nutshell you need to do the following:

  • Install Sun’s Java Development Kit
  • Install Tomcat (I used version 6)
  • Install the GeoWebCache war into the Tomcat Servlet container
  • Configure Tomcat to use Sun’s JDK
  • Set Permissions for Tomcat
  • Edit the GeoWebCache configuration file to define the services you want to cache

First off we need to install the dependencies using apt:

sudo apt-get install sun-java6-bin sun-java6-fonts sun-java6-jre \
libtomcat6-java tomcat6 tomcat6-admin tomcat6-common

Next tell tomcat to use the SUN jdk. To do this edit /etc/default/tomcat6 as root or sudo and add the following lines:

# Added by Tim
JAVA_HOME=/usr/lib/jvm/java-6-sun
# Disabled by Tim based on http://jira.codehaus.org/browse/GEOS-1567
TOMCAT6_SECURITY=no

Now we need to create a user account for the tomcat manager – to do this edit /etc/tomcat6/tomcat-users.xml as root and add a line like the YYY / XXX one shown in the listing below – be sure to replace YYYY with your preferred username and XXXXX with your preferred password.

<tomcat-users>
    <role rolename="manager"/>
    <role rolename="tomcat"/>
    <role rolename="admin"/>
    <user username="YYYYYY" password="XXXXX" roles="admin,manager,tomcat"/>
</tomcat-users>

Next download the geowebcache WAR file from the GeoWebCache download page. Unzip the file and then use the http://localhost:8080/manager/html application to upload the WAR into the servlet container. Then run the following command (not sure if it’s strictly needed) to change permissions of the config files:

sudo chown -R tomcat6 /var/lib/tomcat6/webapps/geowebcache/WEB-INF/*

Nearly done now! Next I edited this file: /var/lib/tomcat6/webapps/geowebcache/WEB-INF/geowebcache-servlet.xml and changed the gwxWMSConfig entry so that it pointed to my local mapserver instance (as shown in line 21 in the listing below).

 20   <bean id="gwcWMSConfig" class="org.geowebcache.util.GetCapabilitiesConfiguration">
 21     <constructor-arg value="http://localhost/cgi-bin/mapserv?map=WORLD_MAP&request=getcapabilities&version=1.1.0" />
 22     <constructor-arg value="image/png,image/jpeg,image/png8,image/gif,application/vnd.google-earth.kml+xml"/>
 23     <constructor-arg value="3x3"/>
 24     <constructor-arg value=""/>
 25     <constructor-arg value="false"/>
 26   </bean>

GeoWebCache will issue a getCapabilities request against my MapServer instance and then bootstrap itself from there.

That’s pretty much all the server side setup work done, all that remains is to restart tomcat and do a quick test:

sudo /etc/init.d/tomcat6 restart

After tomcat is restarted, I pointed my browser at http://localhost:8080/geowebcache/demo and could see a list of layers that corresponded to my original mapserver project. I also used the OpenLayers demos on that page to verify my data was coming through as expected e.g.:

http://localhost:8080/geowebcache/demo/SABIO?srs=EPSG:4326&format=image/jpeg

Note that I appended the “&format=image/jpeg” clause on the end to get jpeg tiles back rather than the default png.

The final step was to test deployment in my own OpenLayers application and see if it all worked. I simply replaced my old direct connecting map layer for one that pointed to the GeoWebCache instance. So this:

new OpenLayers.Layer.WMS(
             "WorldBoundaries",
             "http://localhost/cgi-bin/mapserv?map=WORLD_MAP",
             {
                layers: 'Polbnda',
                transparent: 'false'
              });

became this:

new OpenLayers.Layer.WMS(
 "Polbnda","http://localhost:8080/geowebcache/service/wms",
            {
               layers: 'Polbnda',
               format: 'image/jpeg'
             });

TileCache

In order to use TileCache, you have to have Python installed (which is there by default on Ubuntu). I elected to use the cgi version of TileCache so that the procedure for managing it would be similar to that of MapServer itself. To use the cgi version, one needs to have Apache or similar web server installed.

apache2 apache2-mpm-prefork apache2-utils apache2.2-common

After that I downloaded the most recent version of TileCache from their home page, and extracted it under:

/usr/lib/cgi-bin

Next I edited the configuration file (/usr/lib/cgi-bin/tilecache-2.10/tilecache.cfg) and added an entry like this:

[world]
 type=WMS
 url=http://localhost/cgi-bin/mapserv?map=WORLD_MAP
 extension=jpg
 layers=Roadl

There are various other options that you can use – the cfg file is well documented, but I picked a basic set of options as I did with GeoWebCache. To test, I replaced my OpenLayers map definition from this:

new OpenLayers.Layer.WMS(
             "WorldBoundaries",
             "http://localhost/cgi-bin/mapserv?map=WORLD_MAP",
             {
                layers: 'Polbnda',
                transparent: 'false'
              });

to this:

new OpenLayers.Layer.WMS( "Polbnda",
               "http://localhost/cgi-bin/tilecache-2.10/tilecache.cgi?",
               {
                  layers: 'world',
                  format: 'image/jpg'
               });

I could then pre-seed for the South Africa area like this:

sudo su www-data -c "./tilecache_seed.py --bbox=16,-35,33,-22 world 5 12"

Which pre-seeds zoom levels 5 to 12

Reflections

It took me a couple of hours to download, setup and test both tile cache applications. As is usual I took a couple of wrong turns during the process, but now that I have documented whats needed to be done, doing it again should only take a few minutes in either case. I havent performed any benchmarking so I cant really comment on which system seeds more quickly or works more efficiently. That said the performance of the seeding process is not so critical to me since its pretty much a background process. I could see that if one planned to reseed regularly (e.g. nightly) that this could become a factor.

In terms of ease of setup, I found the TileCache approach much simpler – I always find Java servelets a pain, tomcat to be wobbly and using Java based technologies a generally unpleasant experience. But thats just my personal bias. One thing I did like about the GeoWebCache approach was the way you could just point to a WMS url and then it would use the getCapabilities to generate the demo web page. It gave an immediate sense of achievement and feeling that you had grasped the concepts involved. GeoWebCache also supports publishing to Google Earth which is nice.

TileCache on the other hand was so easy to set up, does exactly what I need, has a few useful command line utilities for seeding and cleaning the cache. Simplicity is always a big win for me since I tend to build up applications by coupling together a bunch of different technologies, so the less involved the process is to set each part of the puzzle is, the better.

That said I didn’t find any definitive reason to use one over the other. I guess for most people the deciding factor will be if you are in the Java/Servlet camp or in the Python/CGI camp.

I’d love to hear from others if they have useful insights into the relative merrits of GeoWebCache versus TileCache…and a big thank you to the respective authors for creating these applications!