This tutorial describes how to create beautiful custom maps, and use them in a Processing sketch. We are going to use TileMill to style our maps, export it, and load the rendered map tiles into PImages. There are two ways of doing that.
A single image as static map. If you simply need a geographical background, or want to put some data onto a fixed map, this is the easy way to go. See the example below.
An interactive tile-based map, where users can zoom and pan. This allows full flexibility and dynamic geo-visualizations. See the example below.
Designing custom maps
In the last years, there have been tremendous changes in the digital cartography field. With the advent of Google Maps and location based services, interactive dynamic maps have become common and wide-spread. This not only led to increased awareness of maps, but to personal enriched geovisualizations and mashups of geo-referenced data. Yet, it was technically difficult to design custom maps, e.g. to use a minimal style for information graphics, or to adapt the map to the style of the visualization.
Fortunately, in 2009 the CloudMade editor was launched, in which users can select various properties and style maps based on OpenStreetMap by themselves. This allowed designers and other non GIS experts to create custom maps, and access the rendered tiles via the web. In 2010, Google Maps followed with their StyledMap, accessible via the Google Maps API. Both are great if you want to easily adapt parts of a map style, and definitely worth to check out. Alas, they allow only a subset of design settings, and both do not provide more enhanced editing functionality such as type selection or fine-grained feature styling.
Now, say hello to the new kid in town:
TileMill – A map design studio
It is a bit more complicated to setup, though, and only available for Mac OS X, Ubuntu and other Linux/Posix systems. But if you are comfortable with Processing, you should be tech savvy enough to use it. After you installed TileMill, point your browser to
http://localhost:8889, and you can start working with the editor.
On the right side, you see an editor, in which you can set and change the style in the CSS-like Carto language. On the left side, you see the map rendered in the current style, which you can interactively pan and zoom to see how the style differs, and how well it looks for a specific region. Besides, TileMill allows you to define a color schema, and use the installed fonts on your system for labelling.
You’ll find more information on the style language in the online manual, but most helpful is the documentation within the distribution. In the editor, click on that book icon to open the inline Carto manual.
The provided data can be used for small-scale maps showing the world, regions such as Europe, or countries. For large-scale maps showing cities, etc. you need your own data. In order to add further geographical features, such as streets or topographical height information, you can add data layers, as well. Conceptually, this is very similar to layers in Photoshop or other graphics software. There are vast amounts of freely available data sets, and the guys at CloudMade kindly provide Shapefiles created from OpenStreetMap data, which can be imported into TileMill (see their blog post).
Now, let’s say you designed a map, and are happy with its look and feel. There are two options of interest to export the tiles of the map. First, you can specify a geographical region and save that map section as single image. Second, you can store the map as multiple tiles for various zoom levels.
Single image as static map
In order to store a TileMill map as single image you can select an area and save the rendered map as PNG file. You can crop the region visually with the mouse, and set the dimensions of the exported image.
Put the exported image in the data folder of your Processing sketch, and simply load it via the
All TileMill maps are using the Mercator projection, so in your sketch you need some conversion method to draw geo-positioned objects onto the map. Use the
MercatorMap utility class to convert from latitude, longitude to Cartesian screen coordinates.
PImage europeMapImage = loadImage("europe.png"); MercatorMap mercatorMap = new MercatorMap(700, 395, 56.54, 39.88, -12.56, 32.34); PVector berlin = mercatorMap.getScreenLocation( new PVector(52.5, 13.34));
In the constructor, define the size of the map in pixels, and set the bounding box of the exported map. Compare the values in the example above with the ones from the TileMill export screenshot.
Now, you can use
getScreenLocation() to project any geo-location onto the canvas.
Download the MercatorMap.java for conversion. See how to use it in an example displaying four cities on a European map (Processing sketch), and an example highlighting three cities on a World map (Processing sketch).
For information on equirectangular (aka plate carrée) projection, e.g. to use with NaturalEarth raster maps, see the section on Visualizing Places in the tutorial “Processing geo information in Wikipedia articles”.
Interactive tile-based map
In order to create an interactive tile-based map, you can export the rendered TileMill map as multiple tile images, and develop flexible map displays with interactivity.
Each tile consists of 256 × 256 pixels. This tile-based approach is done to manage maps at higher zoom levels. Otherwise, a single image showing the entire earth would be too large, e.g. for a zoom level of 10 it would consist of 131.072 × 131.072 pixels.
Exporting your custom map can take a while (e.g. on a MacBook Pro 2.66 Ghz Dual Core, it took 1.5 hours to render and export the tiles up to a zoom level of 8), so you might want to do that overnight.
The exported tiles are stored in the MBTiles format. (
Be aware, their example seems to be outdated. The column is named They fixed it.) The MBTiles file is simply a SQLite database with the map images saved as binary data (blobs).
zoom_level and not
zoom, and they store PNGs with an alpha channel, and not JPEGs.
We can access the tiles by reading the local SQLite database from Processing/Java. For this, we are going to use the SQLiteJDBC library. Now, we can load a single tile with the following SQL query.
SELECT * FROM tiles WHERE tile_column = ? AND tile_row = ? AND zoom_level = ?;
MBTilesLoaderUtils to directly load the tiles to use in Processing. Calling the method
getMBTile(int column, int row, int zoomLevel) returns a PImage, which can be displayed via Processing’s
public PImage getMBTile(int column, int row, int zoomLevel)
column– The column of the tile.
row– The row of the tile.
zoomLevel– The zoomLevel of the tile.
The tile as PImage, or null if not found.
Now that we have access to single tiles, we need to display the map as a whole, and stitch the correct tiles together. In an interactive application, we also need to handle map manipulations, such as zooming and panning.
For Processing sketches with maps consisting of only a few tiles, or non-interactive sketches the MBTilesLoaderUtils might be sufficient. For more sophisticated applications, you might want to try out Unfolding, a map library for Processing.
Unfolding allows creating interactive thematic maps and geo visualizations, and aims at providing easy-to-use and extendable map functionality. See some first tutorial slides on unfoldingmaps.org, the Unfolding examples, or come back later for a tutorial on using this library.