This page last changed on Feb 28, 2007 by jdeolive.

TileCache is a tile caching library developed by MetaCarta Labs written in python.

TileCache provides a Python-based WMS/TMS server, with pluggable caching mechanisms and rendering backends. In the simplest use case, TileCache requires only write access to a disk, the ability to run Python CGI scripts, and a WMS you want to be cached.

This page is being used to capture the design of a JTileCache, that is the integration of TileCache into a java application such as GeoServer.

Motivation

Evaluation

We are presented with a number of different options for the creation of JTileCache. The two most important criteria during evaluation will be:

  • Performance - How well will this implementation perform at the end of the day
  • Maintaince - How much work and effort will this implementation be to maintain

Implementation

At this point, a number of implementation strategies present themselves as viable:

  1. Jython
  2. Full Port to Java

Jython

Jython is a java based implementation of python, which allows for ease of integration between the two languages. With Jython, one is able to call python code from a java application, and vice versa.

A key feature of Jython is the ability to embed jython scripts into a java application. This is achieved by creating a PythonInterpreter instance inside the application, and executing the python scripts accordingly.

//create an interpreter
PythonInterpreter interpreter = new PythonInterpreter();

//execute form python code
interpreter.execfile( "somePythonScript.py" );

//do something the result
PyObject result = interpreter.get( "result" );

Where the python script could be something like:

somePythonScript.py
n = 1 + 1
...
result = n;

Ok... enough with the naive example, how could this method be applied to GeoServer and TileCache? Consider a servlet handling a get map request:

GetMapServlet
public class GetMapServlet extends HttpServlet {

  public void doGet( HttpServletRequest request, HttpServletResponse response ) {

     //get the request parameters
     String layers = request.getParameter( "LAYERS" );
     String bbox = request.getParameter( "BBOX" );
     String height = request.getParameter( "HEIGHT" );
     ...

     //get from the cache
     PythonInterpreter pi = new PythonInterpreter();
     pi.set( "layers",layers );
     pi.set( "bbox", bbox );
     pi.set( "height", height );

     pi.exec( "from Layer import WMSLayer" );
     pi.exec( "s = Service.load( "tilecache.cfg" );
     pi.exec( "tile = s.dispatchRequest( {'SERVICE':'wms','REQUEST':'GetMap','VERSION':'1.1.1','LAYERS':layers,'BBOX':bbox,...)
     pi.exec( "image = tile[1]" );
 
     PyObject image = pi.get( image );
     
     //write the image to the output
     ...
  }

}

And there it is. Although this code isn't not exactly what we would see in a true implementation, it illustrates the general concept. Sooo... onto evaluation.

First the good. This integration strategy will be pretty easy to maintain as none of the TileCache sources need to be modified. All that is needed is some java code to initialize the python runtime and to execute the appropriate scripts. And that is about it for the good... onto the bad.

I actually lied above when I said the TileCache sources can be used as is. Some modifications will have to be made to modify TileCache sources that make calls to Python libraries that are not implemented by Jython. While Jython does implement most the functionality needed, it does not implement all. In particular some of the os library calls made my DiskCache. It also appears that Jython is constantly lagging behind Python and Cython by a few versions, which means that we may be stuck waiting for new versions of Jython to be released to support some functionality that is required.

In terms of performance, this strategy is pretty dismal as well. The jumping back and forth between java and python represents a potentially serious bottleneck that could easily make this strategy unusable. Especially since it must be done for every request. We also really have no way of optimizing in the java environment since we are not playing with the Python sources. Operations that may be efficient in Python may not be so in Java.

Full Port to Java

Document generated by Confluence on May 14, 2014 23:00