This is the third part of the story that I started with

during my experiments I wanted to reach the goal of minimize both the bandwith consuption and the number of vector coordinates that the browser needs to handle, this means that if we need to show complex geometries, for example a set of mountain hiking paths for an overall of 250000 point, we absolutely need a way to simplify features at lower zoom levels.

TileStache doesn’t support this out-of-the box, so I started playing with a clone of the Vector provider and ended up with a vector-simplify branch in my fork.

What I’ve done was basically to add a new “simplify” provider configuration parameter, where you can enter the tolerance for Douglas-Peucker simplification algorhitm in pixel unit. The paramer can be set in TileStache config file as shown here:

  "layers": {
    "pmcollection":
    {
        "provider":
        {
            "name": "vector",
            "driver": "PostgreSQL",
            "parameters": {
                "dbname": "polymaps_test",
                "user": "xxx",
                "port" : "5433",                
                "table": "pm_points_pmcollection"
            },
            "verbose" : "true",
            "simplify" : 0.5
        },
        "allowed origin" : "*"
    }
 }

A picture is worth a thousand words

Some pictures might be the best way to show how this parameter affects the generated geometries:

This is a single tile, the original geometry is in red, the simplified geometry in green/yellow and an over-simplified geometry in blue.

The following overall views show all the details:

Original geometry

Over-simplified with tolerance 50

Simplified with tolerance 0.5

Open issues

The biggest issue I’ve encountered was about getting the tolerance in lat-lon WGS84 starting from pixel units, but let me explain why I choose pixel units in the first place: I think that pixel units are are the best choice because normally we don’t care about feature details which are below 1 pixel, we simply cannot see them. Using pixel units we also get the advantage of using a single number for all zoom levels, a more complicated approach would consist in using separate values for each zoom level. Translating pixel units to decimal degrees is not possible without approximations, I just hope that my approach works in most situations.

Another strange thing I noted in the library is that the bounding box used for clipping (which is a rectangle) is built using 16 points instead of 4. This means that after clipping we end up with a geometry that have many more points that it needs. I’m still waiting for a clarification I’ve asked in the TileStache ML, but in the meantime I patched my branch to use a normal 4 points rectangle and everything seems to work fine (and with smaller geojson responses).

Conclusions

TileStache confirmed to be a valuable tool for web GIS developers, it’s well written and supported and easily expandable, absolutely worths a try.

It's only fair to share...Tweet about this on TwitterShare on FacebookShare on LinkedInPin on PinterestShare on RedditShare on Google+

4 Responses to “TileStache Vector simplify provider”

  • Dario

    It’d be great if the simplification was relative to the zoom, so that at high levels little or no simplification is done, whereas at lower zoom levels much more simplification is done. That is, each level has decreasing levels of simplification.

  • relet

    If you want to save more bandwidth, I have a fix for the float decimal digit issue in JSON: coordinates are rounded to more or less digits after the decimal point depending on the zoom level.

    I also discard invisible geometries, and minify the JSON output by removing whitespace.

    https://github.com/relet/TileStache/commits/minify

    If you want to go one step further, the GeoJSON protocol itself can be reduced by replacing the common keys with shorter one-letter names. This has do be decoded properly in the client library.

    https://github.com/relet/TileStache/commits/minify-cripple