Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Generate and Host Your Own Raster Tiles Customized With Mapbox Studio

DZone's Guide to

Generate and Host Your Own Raster Tiles Customized With Mapbox Studio

Mapbox studio is a useful tool for hosting and serving geospatial data. This article will teach you how to generate raster tiles locally from a given MbS style.

· Web Dev Zone
Free Resource

Prove impact and reduce risk when rolling out new features. Optimizely Full Stack helps you experiment in any application.

If you have never seen maps hosted in Mapbox, you would probably agree on the quality of its designs. The business of Mapbox is to host and serve geospatial data. For this reason, all the great tools Mapbox facilitates are oriented to help their users to prepare and work with their data.

One of the provided tools is Mapbox Studio. Mapbox Studio (MbS) is a desktop application that allows you to create CartoCSS themes that are later used to generate raster tiles. Briefly explained, what MbS does is to download OpenStreetMap data in vector format and render it on the fly applying the specified CartoCSS style.

The result of working with MbS is not a set of tiles but a style, that is, a set of rules that express which color must be used to render roads, at which levels labels appear, with which size, which coloor must be used for the ground, etc. This style can be later uploaded to Mapbox so that raster tiles are generated on the cloud and we can consume the tiles paying for the service.

The question we can ask is: How can we generate the raster tiles locally from a given MbS style?

Well, this article is about that. Continue reading.

Working with Mapbox Studio and Create Your Custom Style

Let’s start from the beginning — download the Mapbox Studio application and install it on your system. Once installed execute it and you will be asked to be connected to the Mapbox platform.

There are two main reasons why Mapbox requires you to register as a user. First, the power of the platform is on the cloud. That includes the styles you create.

Second, MbS retrieves data in vector format from Mapbox servers. When you register as a user you get an API token that identifies your requests. Each time MbS makes a request to extract data it has your token that identifies you as the user. This way Mapbox can control if any user is making a bad usage of their platform.
Screen Shot 2015-07-25 at 23.43.26

Once logged in you will be allowed to create new map styles. The easiest way is to start using one of the starter styles created by the great Mapbox designers:

Screen Shot 2015-07-25 at 23.47.38

Here we have chosen the Mapbox Outdoors style. In the image you can see the style code (CartoCSS which is inspered by CSS) and the resultant tiles obtained from painting the vector information with the given style rules:


CartoCSS is a Mapnikstylesheet pre-processor developed by MapBox and inspired by Cascadenik. It is like a CSS language specially developed to style maps.

Screen Shot 2015-07-25 at 23.54.20

Store the style with a new name somewhere on your computer, for example, customstyle. If you look at your disk you will see a customstyle.tm2 folder has been created containing a bunch of files that define the style rules (take a look they are not dangerous).

Finally, modify some properties, for example @land or @crop colors and save to see the result:

Screen Shot 2015-07-25 at 23.54.47

Great !!! You have created your first custom style.

Generating raster tiles from MbS style

Looking for a solution I discovered the tessera and tl tools. Tessera is a node based command line application. It is based in some modules from mapbox (concretely tilelive) plus others implemented by the author (Seth Fitzsimmons). The result is we can execute tessera passing a MbS defined style, open a browser pointing to a local address and see a map with the raster tiles generated with our MbS style.

Similarly, tl is a node based command line tool we can execute, passing a set of options, to generate a MBTiles file or a pyramid of tiles following the well known z/x/y.png format.


I know about both tools at the article Converting Mapbox Studio Vector Tiles to Rasters from Azavea Labs.

How to install the tools?

NOTE: You need to have NodeJS installed in your system, along with the npm package manager command line tools.

I don’t like to install global node packages (or at least more than the necessary) so I’m going to install the previous tools in a custom folder:

> mkdir tiletools
> cd tiletools

Inside the directory execute next sentence, which install the tessera and tl packages among others:

> npm install tessera tl mbtiles mapnik tilelive tilelive-file tilelive-http tilelive-mapbox tilelive-mapnik tilelive-s3 tilelive-tmsource tilelive-tmstyle tilelive-utfgrid tilelive-vector tilejson

You will see a hidden directory named .npm_modules has been created which contains some subdirectories with the same name as the previous packages.

Running Tessera

Let’s try to run tessera for the first time. Because it is installed as a local node module execute:

> ./node_modules/tessera/bin/tessera.js 

Usage: node tessera.js [uri] [options]

uri     tilelive URI to serve

Options:
   -C SIZE, --cache-size SIZE          Set the cache size (in MB)  [10]
   -c CONFIG, --config CONFIG          Provide a configuration file
   -p PORT, --port PORT                Set the HTTP Port  [8080]
   -r MODULE, --require MODULE         Require a specific tilelive module
   -S SIZE, --source-cache-size SIZE   Set the source cache size (in # of sources)  [10]
   -v, --version                       Show version info

A tilelive URI or configuration file is required.

Tessera requires you pass a URI so it can server its content. It accepts URIs from Mapbox hosted file, Mapnik, Tilemill, Mapbox Studio, …

Repeat again indicating the path to our previously created style indicating the protocol tmstyle://.

> ./node_modules/tessera/bin/tessera.js tmstyle://./customstyle.tm2
Listening at http://0.0.0.0:8080/

/Users/antonio/Downloads/tiletools/node_modules/tessera/server.js:43
        throw err;
              ^
Error: A Mapbox access accessToken is required. `export MAPBOX_ACCESS_TOKEN=...` to set.
...

First it seems like tessera is working at port 8080 but later we get an error about MAPBOX_ACCESS_TOKEN. If you remember from the first section, Mapbox requires all the requests be signed with the user token. So, you need to get the access token from your account and set it as environment variable before executing tessera:

> export MAPBOX_ACCESS_TOKEN=your_token_here
> > ./node_modules/tessera/bin/tessera.js tmstyle://./customstyle.tm2
Listening at http://0.0.0.0:8080/

/Users/antonio/Downloads/tiletools/node_modules/tessera/server.js:43
        throw err;
              ^
Error: Failed to find font face 'Open Sans Bold' in FontSet 'fontset-0' in FontSet

We are close to making it work. The problem now is our MbS style is using a font we have not installed in our system. One easy, but brute force, solution is to install all Google Web Fonts on your system. For this purpose you can use the Web Font Load installation script. In my case I have installed them in the user’s fonts folder ~/Library/Fonts.

Once fonts are installed try executing tessera again:

> ./node_modules/tessera/bin/tessera.js tmstyle://./customstyle.tm2
Listening at http://0.0.0.0:8080/

/Users/antonio/Downloads/tiletools/node_modules/tessera/server.js:43
        throw err;
              ^
Error: Failed to find font face 'Open Sans Bold' in FontSet 'fontset-0' in FontSet

That’ s a bit strange, we have just installed the fonts but they are not found. What is happening? Well, tessera uses mapnik to create the raster tiles and it looks for fonts in the folders specified by the environment variable MAPNIK_FONT_PATH, so let define the variable:

> export MAPNIK_FONT_PATH=~/Library/Fonts/

and execute the script again:

> ./node_modules/tessera/bin/tessera.js tmstyle://./customstyle.tm2
Listening at http://0.0.0.0:8080/

/Users/antonio/Downloads/tiletools/node_modules/tessera/server.js:43
        throw err;
              ^
Error: Failed to find font face 'Arial Unicode MS Regular' in FontSet 'fontset-0' in FontSet

OMG !!! This seems a never ending story. Now we need to install the Arial Unicode font. Look for it, install in your system and execute tessera again:

> ./node_modules/tessera/bin/tessera.js tmstyle://./customstyle.tm2
Listening at http://0.0.0.0:8080/

Great !!! It seems tessera is working fine. Let’s go to open our browser pointing to http://localhost:8080 and see the result:

A map implemented using Leaflet web mapping library is shown, rendering raster tiles that are created on the fly. Look at the console to see the tessera output information:

We can see how tiles at current zoom, the zoom level 8, has been generated.

At this point we have tessera working but what about generating a local pyramid of tiles for a given zoom level and a given bounding box?

Generating a custom pyramid of tiles with tl command line tool

Before continue we need to know which bounding box we want to generate, the whole world? or only a piece. In my case I want three zoom levels (7, 8 and 9) wrapping Catalonia.

There are some online tools you can use to get the bbox of a region, but one I like it the Bounding Box Tool from Klokan Technologies.

The tl tool can run three main commands but we are only interested in the copy one, which copies data between two providers. In our case the MbS style is one provider and the file system is the other. Run the tl command to see the available options:

> ./node_modules/tl/bin/tl.js copy -help
'-p' expects a value


Usage: node tl.js copy <source> <sink> [options]

source     source URI
sink       sink URI

Options:
   -v, --version                 Show version info
   -b BBOX, --bounds BBOX        WGS84 bounding box  [-180,-85.0511,180,85.0511]
   -z ZOOM, --min-zoom ZOOM      Min zoom (inclusive)  [0]
   -Z ZOOM, --max-zoom ZOOM      Max zoom (inclusive)  [22]
   -r MODULE, --require MODULE   Require a specific tilelive module
   -s SCHEME, --scheme SCHEME    Copy scheme  [scanline]
   -i FILE, --info FILE          TileJSON

copy data between tilelive providers

So let’s go to execute the command to copy data from our MbS style to the local tiles folder. We want to generate tiles from zoom level 7 to 9 and indicating a bounding box wrapping Catalonia.


Remember the -b options must be indicated as [minLon minLat maxLon maxLat].

> ./node_modules/tl/bin/tl.js copy -z 7 -Z 9 -b "0.023293972 40.4104003077 3.6146087646 42.9542303723" tmstyle://./customstyle.tm2/ file://./tiles
Segmentation fault: 11

Ough !!! That hurts. A segmentation fault. After looking for a while I realized it was a bug. To solve it, go to tl/node_modules/abaculus/node_modules and remove the mapnik folder dependency. It is redundant because there is one installed in parent folder.

Execute the command again and see the output:

The tl tool has created a local tiles directory and generated all the raster tiles for the given zoom levels and bounding box. The output shows, in addition, the time required to generate each tile.

That’s all. Now we only need to host the tiles at our own servers !!!

 

With SDKs for all major client and server side platforms, you can experiment on any platform with Optimizely Full Stack.

Topics:
css ,tessera ,cartocss ,mapbox

Published at DZone with permission of Antonio Santiago, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}