Monday, 30 December 2013

A FireMonkey client for the DWS Terapixel Mandelbrot data set

You may have seen Eric Grange's precomputed Mandelbrot set data - read the Christmas announcement and the followup. He has generated and is hosting the fractal as a multi-level tiled data set: that is, as a structure of varying levels of detail, where each level of detail is twice as large as the one before. His tiles are not images, but rather a table of the number of iterations required for each point.  These values can then be mapped to colour as the client application decides.

Quick overview of tiled level-of-detail data

You can picture this as a pyramid, or as an infinitely divided square. The first level, level 0, has one tile. Level 1 subdivides level 0's tile into two on each axis, so four total.  Level 2 subdivides each of these tiles, as so forth.  Since each tile has the same dimensions in pixels, but represents a smaller area of the data, you get higher and higher resolution data in each tile.
This is a common method of storing similar data - I've previously used it for geographic maps, for example. Often tiles will be images, but in this case they are data that can be converted to images.
As of Dec 27, there are fourteen levels (0-13.)  At level 13, there are 213 tiles in each dimension making a Mandelbrot set 8192 x 8192 tiles on a side.  At 256 pixels square, this is 2097152 pixels a side, or 4398046511104 pixels in total.  That's quite a lot.  Add in the other smaller levels and you have an enormous of data, many gigabytes.  For comparison, zooming in from the whole earth to a few meters is only a few more orders of magnitude; at 1 pixel/meter, zoomed in to the maximum zoom on this set makes the whole Mandelbrot set, in pixel space on your screen, the size of a large country.

I thought it would be a fun project to write a small viewer app for this dataset, so here it is: a cross-platform (Windows and OS X) tiled data viewer written in Delphi and FireMonkey.

Why write it?

  • To find out first-hand what it's like writing a non-trival (although admittedly small) app using FireMonkey.  Some people rave, some people complain: who's right?  There's only one good way to find out. I will write about this in a followup post.
  • To provide an example of using a tile API.  If you end up having to implement one of the common tile APIs out there and you've never had to deal with tiles, navigation, zooming and pixel-perfect dragging/scrolling at different zoom levels, this code is simple and worth reading. It's also open-source (MPL.) You're welcome to use it.
  • Because everyone like knowing people are using code they've written, and I hope Eric finds it interesting someone's written an app to use his server fractal API & data.
  • For fun!

Features:

  • Smooth scaling: the zoom level does not have to match a tile level. High-res tiles are loaded and scaled down.
  • Smooth UI: grab and drag to scroll, animated scaling as you zoom in or out
  • Asynchronous loading: tiles are downloaded and converted to image data in another thread.
  • Cross-platform, from the one project and source code (only one $ifdef required for low-level pixel color handling)

Random notes:

  • Despite reviewing FireMonkey when it was released with XE2, this is actually my first non-trivial FireMonkey app.  It was written with Delphi XE2, and I will upgrade it to XE4.  My aim here is to see what the experience is truly like using both the first FMX and upgrading to a new FMX version.  I will write an article about my impressions soon.
  • In addition, unlike my other open-source projects (which are hopefully useful libraries, not apps) I've hosted this one on a Mercurial server. I had read about but hadn't used a distributed version control system before, so starting a new project was a good opportunity to try one out.  It's an interesting paradigm, although for a sole developer not much different to a standard system like Subversion.

Future:

  • While the DWS Mandelbrot set is cool, there's lots of other tiled data out there too.  With some refactoring, it would be easy to change this app to support a wide variety of tiled data sources and turn it into a generic tiled data viewer.  One immediate candidate is Bing Maps's tile API.  Nokia / HERE maps also has a tile API, and Google can have one with a bit of hacking / hope - its map APIs are not as extensive for non-web platforms.  I would be interested to hear of any data sources you are interested in, and if I expand the product to support each API as a plugin then anyone could implement support for a specific type of data.
Meanwhile, it's been a fun way to spend a day or two!

Download: