Now that I’ve got a working animated tile class, it’s time to look and see what performance improvements I can make to it. As in my first post in this series, the frames of my animation are going to be built from weather RADAR data collected from the NOAA at regular intervals in time (every 15 minutes), over a 6 hour period. This means that, every time my animation runs through a complete cycle, I will have requested 24 times the number of tiles normally required to construct the background of the map display. The absolute key to making this solution usable was going to be in ensuring those tiles were as small filesize as possible.
Reducing the Bit Depth
My weather data was retrieved and the tile images constructed dynamically using a PHP script. Since I wanted my tiles to retain transparency (so that they could be overlaid on top of other layers), but didn’t want to use GIF format, my only choice was to opt for PNG files which can be created with the PHP imagepng function.
By default, PHP creates true colour (i.e. 32bit) PNG images. However, my NOAA radar imagery was only using a 256 colour palette so, as suggested by a commentator on one of my previous posts (thanks Chris!), I could save some space without affecting image quality by ensuring all my tile images were saved as 8bit PNG rather than 32bit PNG. To compare, here’s the RADAR image for tile quadkey 02311, recorded at 10:15am on 27th May 2011:
32Bit PNG (192kb)
8Bit PNG (9kb)
192kb reduced to 9kb with no change in appearance – that’s a pretty good start!
Compressing the Tiles
My next option was to compress the tiles. The PNG file format uses the Deflate compression algorithm, which has two key features: a.) It’s a lossless algorithm, so (unlike JPG) there is no reduction in image quality in a compressed image file, and b.) it has a static decompression rate. What that means is that, however much you compress a PNG file, it will not take longer to decompress. Unlike some archive formats, there is no trade-off between having a smaller compressed filesize, only for it to take longer to unpack or for it to be lower quality – with PNG, compression is always desirable. You can read a good introductory guide to PNG compression at http://optipng.sourceforge.net/pngtech/optipng.html
There are a number of different PNG compression tools out there. For comparison, I tried both an online service (PunyPNG), and a small downloadable Windows application that provides a front-end for a series of command-line PNG utilities (PNG Monster). Both are free to use, and don’t add any watermarks to your images.
PunyPNG compressed my 8bit PNG, original size 9,212 bytes, down to 7,270 bytes (a 22% reduction). PNG Monster did even better, reducing it to just 5,793 bytes (a 37% reduction).
PunyPNG compressed 8Bit PNG image (8 bytes)
PNG Monster compressed 8Bit PNG image (6 bytes)
What makes PNG Monster even more useful is that you can set it to batch process and compress all the PNG files in a directory, rather than having to upload them one by one to an online webservice. The interface isn’t much to look at (except for the nice icon of the Cookie Monster), but if it gets the job done, who cares?!
I set it to work in a directory that contained 256 tiles representing the tiles for one frame of animation, at zoom levels 5, 6, and 7. This reduced the total size from 1.2Mb down to 566Kb – less than half the original size:
The Only Way is… PNG?
(If you’re not au fait with pop singles from the late 1980s, that title was meant to be an homage to Yazz. Oh, never mind…).
I was pretty pleased with the results from PNG monster, but there was just one more option I wanted to explore. My reason for choosing PNG was because it supported transparency, and could therefore be added as a separate tilelayer overlaid on top of other background layers within the AJAX control. For example, you could place the animated weather tilelayers on top of the base aerial imagery tiles, or the road map tiles:
|Base map style||Transparent PNG||Result|
But what about, rather than creating the RADAR image as a transparent layer, I created an opaque tile that showed the data ready overlaid onto a Bing Maps imagery tile? That way, I could save the tile as a JPG file instead and take advantage of its (potentially) greater compression ratio.
The aerial image tile shown above, http://ecn.t1.tiles.virtualearth.net/tiles/h02311.jpeg?g=685&mkt=en-gb&n=z, is 24,128 bytes. Setting a compression ratio of 65%, I could create a JPG tile of almost exactly the same filesize as the original Bing Maps tile, but incorporated the radar image as well:
While, at first, I thought that embedding the RADAR imagery onto the background tile image might have been a good idea, (and, it would be, if I was only trying to display a single static tile combining weather data and imagery), the end JPG tile ended up being much greater size than my compressed PNG image tiles. In every frame of the animation, I’d be downloading the entire background map image for that tile again, and I’d also lose the flexibility of being to overlay a transparent layer on top of any other layer. Idea aborted – back to PNGs!
In the next (and probably final) post in the series, I’ll try to pull this all together into a reusable animation module.