TileMill for Processing
by Till Nagel.
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.
Basic
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.
Advanced
An interactive tile-based map, where users can zoom and pan. This allows full flexibility and dynamic geo-visualizations. See the example below.

Custom map adapted to style of a visualization. Markers are dynamically added in Processing.
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
TileMill is a map design environment, which – as they put it – “enable[s] artists to design maps”. Sounds good? Indeed, it is.
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 loadImage() method.
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 = ?;
Use 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 image() function.
public PImage getMBTile(int column, int row, int zoomLevel)
Parameters
column – The column of the tile.row – The row of the tile.zoomLevel – The zoomLevel of the tile.Returns
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.



[...] Nagel teaches you how to design custom maps in Processing with TileMill. Could come in handy one day. Saving for later. [via] AKPC_IDS += "17535,"; [...]
This was a great read. Thanks for sharing. Would also love to see a working example of your sketch embedded here.
Hi, how to create a map tile mill map box and i want to make a circle on a particular area of map with mouse over and mouse click event . Please help me out !
Thanks
[...] Nagel has a tutorial on using custom maps as backgrounds in Processing sketches. The solution uses TileMill, a map design environment which allows you to export a [...]
Thank you. I’ve been working toward this and your instruction is very helpful.
Thank you! I’m looking forward to try this out!
Amazing. This is exactly what I needed. Thank you so much.
[...] want to use TileMill for processing you should read the great tutorial of my lecture Till Nagel: TileMill and Processing He also describes how to use TileMill for his neat library [...]
[...] using the basemap in Processing, you best refer to the Simple static map example by Till Nagel. He offers a nifty MercatorMap class for download, which one can use for handling [...]
Hi, thanks a lot for this article, it explains clearly the use of TileMill. I am working on an application using processing to simulate traffic, what do you recommend for protting dots across the ways on the tile? I was thinking in parse the .osm data file to find the nodes, but i’m guessing if there could be a better way to do it. thank you.
Pato,
That depends in which format your traffic data is, and how generalized the provided geospatial edges are. You might want to look into Map Matching and start from there.
If you do not have any data yet, and want to go for simulating just some vehicles in a game engine or whatnot, then the simplest way would be to manually record pathes on a chosen map, and use those geo-locations in your application.
Thank you for your advice, actually I have not traffic data yet, I was thinking in parsing the .osm data downloaded from OSM and then build the ways and related objects. The main goal of my proccessing app is to simulate traffic on my city map. I have done the map display with the help of your article and unfolding, so now i’m working on a way to animate dots on the data ways.
[...] to visualize the most interesting parts of the data. There is a lovely tutorial on how to do this here. One of the questions my friends and I were debating during the game was “Whether the NFL or [...]
Hi,
Does Tilemill have a function in which a country will highlight upon being scrolled over by the mouse? Or, is there some sort of clicking function where if the user was to click on a country, tilemill will be able to decipher which country was clicked and retrieve data for that specific country from an sql table?
Paul,
TileMill indeed does offer that. Check their website, and look for the Interaction Editor, or – if you’ve installed TileMill already – try out the map with interactive countries. Does exactly what you want. See also http://mapbox.com/tilemill/docs/crashcourse/tooltips/
If you want to have this functionality in Processing, you can use Unfolding ( http://unfoldingmaps.org/ ) and do that based on either some external lookup API, or internally with some polygon data for the countries. Let me know, if you are using Unfolding.
I’m trying to do just this — create hover and linking in Processing using polygon data from a shape file.
I created and exported a map using TileMill, then read it into Processing as an interactive map using the steps outlined here:
https://forum.processing.org/topic/unfolding-maps-streaming-tilemill-hack-howto
The java.awt/Polygon class looks like a good way to implement detection of polygon regions in Processing. Using this you can construct polygons and use the Polygon.contains() function to detect if the mouse is within the polygon region as described here:
http://wiki.processing.org/w/Using_AWT's_Polygon_class
What I’m having trouble with is how to turn the SHP file into usable sets of polygon coordinates that are linked to the map in my Processing sketch. I am new to GIS so any help would be greatly appreciated.
Eric
Eric,
That is a good way of using TileMill tiles in Unfolding. Yet, for a deployed application I’d suggest accessing the exported MBTiles instead of the rendered tiles from a running TileMill instance.
AWT Shapes are a possibility, while I typically use Tocixlib’s geom package, e.g. http://toxiclibs.org/docs/core/index.html?toxi/geom/Polygon2D.html
Regarding your main question: This is out of the functionality of Unfolding. You may want to convert the Shapefile into GeoJSON or some other easier to read format. You could use GDAL for that (e.g. ogr2ogr -f “GeoJSON” output.json input.shp input), and import the JSON file into Processing, and converting them into your internal polygons.
can we use a external map tile mill map box ?
I am having trouble loading a mbtile in my processing sketch and I am not having a lot of luck with the examples on the googlecode page. Do you have a simple sketch you could share?
We are in the process of moving to Github, where you can find an example of how to use custom MBTiles in a Processing/Unfolding sketch.
https://github.com/tillnagel/unfolding/issues/16
Thanks for the great tutorial!
Is there an easy way to get screen coordinates for GPS coordinates when using Unfolding and mbtiles? Could I use the same method you used with a single png image (mercadorMap)? I was able to get it to work with a single image but wasn’t sure how to do it when I make the map zoom-able.
See also my comment directly above. With the current release 0.8 it is not (that easily) possible. We are planning to publish a beta of 1.0 next week, where this will be part of the Unfolding library.
For now, you can download the develop-branch from our github. Then, take a look at the examples MBTilesApp and SimpleNonMarkerApp.
Ah thanks, I forgot to look back at the examples… sorry. That was enough info to get me going, although I ended up using MapBox.WorldLight.provider for my map instead of a mbtiles file.
Now that I got this working is there a way to export this as an applet when using map providers? Every time I try the applet never loads, I even tried signing the applet. Thanks again.
Hi, thanks for your tutorial. I totally follow you until the “Interactive tile-based map” section where i get lost. How can i get the map shown in the second figure at the start of the post. Is there a link that explain step by step on how to get to that result?
Thanks in advance,
Fernandp