Till Nagel


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.

Map with markers showing the cities London, Berlin, Venice, Istanbul

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 zoom_level and not zoom, and they store PNGs with an alpha channel, and not JPEGs. They fixed it.) The MBTiles file is simply a SQLite database with the map images saved as binary data (blobs).

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)
Loads the map tile at the given position for the given zoom level from the specified MBTiles database, and returns it as image.
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.

28 comments on ‘TileMill for Processing’

  1. [...] 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,"; [...]

  2. arpit says:

    This was a great read. Thanks for sharing. Would also love to see a working example of your sketch embedded here.

    • shivraj sharma says:

      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

  3. [...] 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 [...]

  4. DED says:

    Thank you. I’ve been working toward this and your instruction is very helpful.

  5. Ola says:

    Thank you! I’m looking forward to try this out!

  6. Justin Brown says:

    Amazing. This is exactly what I needed. Thank you so much.

  7. [...] 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 [...]

  8. [...] 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 [...]

  9. 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.

  10. Till Nagel says:

    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.

  11. [...] 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 [...]

  12. Paul says:

    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?

    • Till Nagel says:

      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.

  13. Eric says:

    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

    • Till Nagel says:

      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.

  14. shivraj sharma says:

    can we use a external map tile mill map box ?

  15. P'arry says:

    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?

  16. Jon says:

    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.

    • Till Nagel says:

      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.

      • Jon says:

        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.

  17. Fernando says:

    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

  18. rico says:

    is there a way to show directions from one point to the other in map?? tried searchin with no luck..

  19. [...] 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 [...]

Leave a Reply