Mapbox Cookbook - Sample Chapter
Mapbox Cookbook - Sample Chapter
ee
Mapbox Cookbook
Mapbox Cookbook
The Mapbox platform offers all the tools and APIs required to create and publish a totally customizable map.
Starting with building your first map with the online Mapbox Editor, we will take you all the way to building
advanced web and mobile applications with totally customizable map styles. In the initial few chapters we
will dive deeper into the TileMill and Mapbox Studio components of Mapbox and use them to generate
custom styled map tiles and vector maps. Furthermore, we will publish these custom maps using PHP,
Node.js and third-party tools such as GeoServer. By the end of this book, you will learn about Mapbox GL
and how to create a fully functional, location-aware mobile app.
Sa
pl
e
and problems
problems efficiently
real-world problems
$ 39.99 US
25.99 UK
P U B L I S H I N G
Bill Kastanakis
Mapbox Cookbook
Over 35 recipes to design and implement uniquely styled maps
using the Mapbox platform
P U B L I S H I N G
Bill Kastanakis
Preface
Maps are an essential element in today's location-aware applications, but they lack variation
and customization. The Mapbox platform offers the tools and APIs required to totally
customize, populate, and publish a map.
In this book, starting with the basics of Mapbox Editor for your first map styling steps, we
will take you all the way to building advanced web and mobile applications with completely
customizable map styles. The book focuses on the CartoCSS styling language as well as
Mapbox tools and its JavaScript API, which inherits from Leaflet and is one of the most
established, robust, and easy-to-use libraries.
We will then introduce two core Mapbox tools: TileMill and Mapbox Studio. Using them, we will
generate custom-styled map tiles and vector maps. We will then move on to how to publish
your custom maps using PHP, Node.js, and third-party tools such as GeoServer.
The next step is to start using the Mapbox JavaScript API and Leaflet to create different
visualization map styles, such as a choropleth map and a heat map, and add user interactivity
using UTFGrid.
We will continue with the advanced chapters and focus on integrating with third-party services
such as Foursquare, Google Fusion Tables, CartoDB, and Torque to help us populate and even
animate our maps.
Finally, we will end the book with a chapter dedicated to mobile devices. You will learn about
Mapbox GL and how to create a fully functional, location-aware mobile app, which will use the
map styles created in the earlier recipes.
This book is fast-paced, and the recipes are easy to follow. While it focuses on a recipe
approach, it dives into the core concepts and theory of the technologies used to help you
understand the theory required for GIS, web, and mobile development.
Preface
Introduction
Up until now, we have used Mapbox Editor to create and customize our maps. We have seen
how feature-rich and powerful it is and how, using just a web interface to customize your map,
it provides you with so many possibilities. We were able to totally customize the color theme,
add markers and features, and customize their appearance.
Although powerful, there are times when you need more control. What if we want to change
the widths of the lines that represent roads? What if we want to totally customize this width
over different zoom levels? What if we want a custom font, or even better, a different font (or
font size) at each zoom level? What if we want to hide or show features when a user zooms in
or out?
The possibilities are endless, and the power of unlocking this level of customization lies in
a language called CartoCSS. Well, it's not exactly a language like C++ or PHP, with objects
and complicated memory management, but it is a much more user-friendly, stylesheet-like
language that shares a lot of similarities with the well-known CSS.
45
Understanding TileMill
TileMill is a standalone application that helps us add various layers of (map or vector) data,
write CartoCSS, preview the results, and finally export the tiles:
To better understand how it works, we will explain the workflow to create, customize, and
publish our own custom-styled map.
46
Chapter 3
If you open TileMill and create a new project, you will notice that it only shows a global map
with coastlines. If you try to zoom in, you will see that there are no roads, labels, or other
detailsjust a solid white color for land and blue for water. In order to start working with
TileMill, you need to import the data you need.
TileMill supports a variety of data from different sources; for example, it allows us to import
shapefiles, which contain geographical points, lines, or polygons. Using shapefiles, you
can import features such as roads, coastlines, and buildings. Shapefiles support a single
geometry type.
It also supports GeoJSON, a flexible file format that supports different geometry types. Many
agencies provide data in this format; for example, if you request data for earthquakes in
the last n days, you will receive a GeoJSON file that includes points indicating the recent
earthquake locations.
You can even create images, such as GeoTIFF files, with data that you may want to overlay
on your maps. This feature is extremely flexible; for example, you may want to overlay weather
data, such as clouds, on top of your maps.
KML is another supported format popularized by Google. However, TileMill does not support
many of the features of KML, such as images, flythroughs, and embedded styles, so keep this
in mind when importing KML files.
TileMill also supports importing data from databases such as SQLite and PostGIS, which is an
extension of PostgreSQL. You can connect directly from TileMill to a database and run queries.
Each separate file must be imported in a separate context, which TileMill calls a layer. Each
layer can then be separately styled using CartoCSS. We can use the attributes found in the
layer and style them differently. Once we have imported and styled all the layers, the last
step is to export the map in order to publish it. We cannot simply export a huge image from it
because, even for tiny areas with a zoom level of 15 or similar, it would export an immersive
image in a size that would not be possible for a normal computer to read due to memory
limitations.
For this reason, TileMill splits this huge image into separate tiny tiles. These tiles are then
uploaded to Mapbox and displayed to the user.
If you have ever noticed a map loading on a slow connection, you must have
seen tiles appearing as the map loads.
Well, at this point, I imagine that you have begun to understand how powerful the whole
process must be to import any data we want in different formats, combine them all together
using layers, and style them individually with absolute control!
47
48
Chapter 3
Let's find out how Mapbox Studio works.
We learned in the previous section that we need to import our data into TileMill. Well, this is
not the case with Mapbox Studio because we immediately have access to Mapbox Streets,
Mapbox Terrain, and Mapbox Satellite data. We do not need to search for the region of
interest, extract it, and use it, as we do in the case of TileMill. With this simple choice, we can
have access to data from the entire world down to the finest detail.
We can use Mapbox Streets as a source; this provides us with the vector data required to
build a map. We can also select one of the other sources of Mapbox, such as Mapbox Terrain
or Mapbox Satellite. We can even combine all these sources and overlay them one on top of
the other to use the features provided by these different sources.
You may ask, what if I want to import and use my custom data and then overlay it on top
of these maps? Well, this is easy too. You can import your own data into Mapbox Studio
by converting data from traditional formats, such as those supported by TileMill. Once it is
imported, you can then upload it to your Mapbox account, and it will immediately become
available for use as a source in Mapbox Studio. It can then be overlaid on top of other map
data.
Mapbox Studio works with vector tiles, and because of this, we do not need to export the
resulting styled map in separate tiles. With Mapbox Studio, we will simply upload our own
custom-created map into our Mapbox accountjust like that! We don't have the hassle of
waiting for hours for the tiles to be exported, neither do we need tons of hard drive space, and
we are not required to have a high upload speed in order for the upload to be completed in
reasonable time. The whole process is nearly instantaneous.
In spite of the importing and exporting capabilities of Mapbox Studio and the differences from
TileMill in the technologies that it uses, such as the vector tiles, we still find a CartoCSS editor,
and we can style our map using CartoCSS just as with TileMill.
Another handy feature of Mapbox Studio is the ability to automatically adapt to high-resolution
displays (retina displays). In the case of TileMill, we need to export a separate double-sized
tileset to use with these displays, causing the exported time, hard drive space, and upload
time to double.
Mapbox Studio provides us with all the typography that we should need. It comes bundled
with 300 professional quality fonts to use on the maps.
Fonts are provided free of charge for exclusive use in maps with Mapbox
Studio. It's actually not allowed to use them in any other case.
49
Now, we have come to a point where you may ask, "what's the catch?"
Using Mapbox Studio is not free; it's a paid service. There is a starter plan offered by Mapbox,
which is free, but it's very limited in what you can do with it. Mapbox plans are based mainly
on map views, storage, and the custom styles you can host.
The starter plan at the time of writing this book, apart from allowing 3,000 views per month
and 100 MB storage, has just one custom style, which means that we cannot have more
than one custom dataset overlaid on our vector maps. Luckily, Mapbox introduced a basic
plan for just $5 per month, which offers three styles, 1 GB storage, and 10,000 views per
month, so anyone can now start working with it without being limited. A while ago, Mapbox
had a standard plan for $49 per month. While this was not a showstopper if you planned to
use what Mapbox offers professionally, it was for people who just wanted to explore Mapbox
Studio's capabilities.
By this time, you may be thinking that if Mapbox Studio and other Mapbox technologies are
currently open source, what stops us from hosting the maps in our own servers? Well, nothing
stops us, but deploying the whole Mapbox stack to our own server is extremely complicated
and beyond most people's skills.
50
Chapter 3
Introducing CartoCSS
The time has come to explain how we can fully customize our maps to create the style we
want.
CartoCSS is a powerful stylesheet-like language powering TileMill and Mapbox. It's extremely
powerful and only limited by our imagination. If you are familiar with CSS for the Web, you will
feel right at home when you start working with CartoCSS. If you have never developed for the
Web, don't worry at all. Learning CartoCSS is extremely easy and fun.
Let's begin by explaining how it works.
51
Observe the #sf-lines layer name in the Layers management dialog in the lower-left corner
of the screen.
Certain attributes can only be applied to a specific typewhich are called symbolizersfor
example, line-width and line-color. These refer to the thicknesses and colors of lines
and can obviously be applied to lines only, while others, such as fill-color, can only be
applied to polygons.
The style types are called symbolizers in the Mapbox language (which originates from Mapnik,
a technology used to render maps).
There are currently 10 symbolizers in TileMill, and each one can be applied to a certain type
of geometry. The symbolizers are as follows:
52
Chapter 3
Raster (rasters)
Buildings
We can repeat this process to specify as many selectors as we want, and in each one, we can
change as many parameters as we want.
Filters
CartoCSS allows us to use filters in order to specify ranges; for example, we can use the
[zoom = 10] filter to apply styling only at zoom level 10.
Let's consider an example of how we can use zoom filters:
[zoom < 16] {
#sf-lines[highway="primary"] {
line-width: 3;
}
}
In this example, the first selector is zoom < 16, which means only the instances when the
zoom is less than 16. From the #sf-lines layer, we select all the primary roads. Then we set
line-width to 3.
In the preceding example, we used zoom to adjust the line width of the roads. As you may
have noticed in various mapping services, maps usually display less detail as you zoom out,
which happens because they don't want to overwhelm the user by displaying information that
does not make sense at these zoom levels.
Imagine a map of the United States zoomed out to a level where every state is visible on the
screen. What would happen if we were to display, at this specific zoom level, every street
name down to the smallest walk path?
Comparisons
As you may have noticed in the preceding section, we used comparison filters to specify the
criteria. We have already used highway="motorway", which is a text filter, and [zoom <
16], which is a zoom level filter.
Let's take a look at some more examples to understand the power of filtering our content.
For zoom level filters, we can limit the zoom levels to a specific range using the following code:
#sf-lines[zoom=>5][zoom<=12]
53
Here, from the earthquakes layer, we are selecting the points between magnitudes 5 and 6.
Note that the equals sign is missing.
For text comparisons, we can use the following code:
#sf-lines[highway != "primary"]
From the #sf-lines layer, select everything except primary highways. Alternatively, you can
use the =~ operator to specify a regular expression, as follows:
#sf-lines[highway =~ ".* Highway"]
In the preceding example, both major and secondary highways will be selected.
This will set the background color to blue. The color value is represented in hex.
To simplify our work and have an easier time when tweaking or fine-tuning our design,
CartoCSS allows us to use variables to define colors (and many other values), as follows:
@water: #b5e3ff;
Map {
background-color: @water;
}
Water {
fill-color: @water;
}
At the beginning, we defined a variable called @water with a hex value of #b5e3ff. We set
this variable as the color value for both the background and the fill color of water. This will
save us from replacing multiple values within the editor when we need to make a change.
54
Chapter 3
In the TileMill editor, colors are also represented with a color swatch directly below the text. You
can simply click on the swatch, a color palette will appear, and you can select a color you like.
Styling lines
Let's explore some common techniques of styling lines.
The attributes we already know for lines are line-color and line-width. Another useful
attribute is line-join. It changes how lines appear at the points where they join other lines.
Let's consider an example of how it looks if we don't set this attribute at all, which means that
it uses the default line-join parameter, miter:
55
You can also try setting it to bevel and spot the differences as compared with the preceding
screenshots.
Another useful parameter is line-cap, which sets how lines look at the ends. You can set it
to butt (default), round, and square:
The line-dasharray property can take a comma-separated list of pixel widths as a value.
Each value represents a dash and a space in this order. For example, line-dasharray:
24, 12 will create a dash of 24 pixels and a space of 12 pixels.
56
Chapter 3
You can set as many values as you like to create more complex styles; for
example, line-dasharray: 24, 12, 15, 7, 12, 3 is perfectly
valid.
Note that we combined line-dasharray with line-cap and line-join to get the
rounded look.
Styling polygons
Polygons are filled areas. We usually style them with a solid color or pattern. Polygons can also
be styled with the attributes that we saw before, such as line-width and line-color, but
let's explore some new ones that work specifically for polygons.
The most common one is polygon-fill. It simply fills the polygon with a solid color. Take a
look at the following code:
#countries {
polygon-fill: #aaa;
}
We can specify the opacity of the polygon using the polygon-opacity attribute, as follows:
#countries {
polygon-fill: #aaa;
polygon-opacity: 0.50;
}
57
This pattern is only applied to the polygon that we defined within our selector. To apply
patterns in the background, we can use the background-image property, as follows:
#countries {
background-image: url("pattern01.png");
}
58
Chapter 3
Styling labels
It's almost certain that at some point, we will need to style labels. By this, we mean how the
text for road names, cities, or countries will look.
The most basic form of styling text can be found in the following example:
#countries {
text-name: [NAME];
text-face-name: 'Arial Bold;
}
First of all, we need to fetch text from our layer data. We can do this using text-name:
[NAME], where NAME is the attribute name of our layer.
We also need to specify text-face-name. This is the font name that will be used by TileMill
to display the text on the screen. This is not the font filename but how the font is named
internally. You can use the fonts browser within TileMill to browse the available fonts in your
system and see their internal names.
We can change the text color using the text-fill property and the text size with the textsize property.
There is a property called text-halo-fill, which in simple words is the outline color of the
font; however, in order for it to be visible, you have to also specify the text-halo-radius
value with the radius in pixels.
A complete styled text will look similar to the following example:
#countries {
text-name: [name];
text-size: 16;
text-fill: @text;
text-face-name: "Arial Bold";
text-halo-radius: 1;
text-halo-fill: #AC8812;
}
59
If we look at this screenshot, the street labels are not aligned with the streets. The map looks
a bit weird because in many cases we can't tell which label belongs to which street. It would
be much better if we could align the labels to the directions of the streets.
To do this, we can use the text-placement property. It takes four different parameters, but
the most commonly used one is line, which aligns the label in the line's direction:
60
Chapter 3
The complete selector can be found in the following example:
#countries {
text-name: [name];
text-size: 16;
text-fill: @text;
text-face-name: "Arial Bold";
text-halo-radius: 1;
text-halo-fill: #AC8812;
text-placement: line;
}
Attachments
You may have noticed in the preceding screenshot that the selector contains another nested
selector that starts with two double colons (::). This type of selector is called attachments.
It's a way to instruct TileMill to draw the same element again, but this time, we will style it with
the properties modified within the selector closures.
If we start using two double colons, we must specify a name. This name can be whatever we
want; we can name it so as to remember what this attachment does. Then, in this context, we
can specify any properties that we want to modify.
Let's consider an example:
#countries {
line-color: #0000ff;
line-width: 6;
polygon-fill: #dd0000;
::second-outline {
line-color: #ff0000;
line-width: 3;
}
}
In the preceding example, TileMill draws an outline of the #countries layer, with a width of 6
pixels and the color blue. Then, at ::second-outline, it draws the layer again, but this time
with the color red and a width of 3 pixels.
61
The power of CartoCSS lies in the concepts that we explained in the preceding section.
By following these simple rules, you can transform your map to whatever you have in your
imagination.
62
Chapter 3
How it works
Once TileMill is installed and you have opened it, you will be greeted with the templates
screen, where you can select one of the predefined templates, one of your previous projects,
or create a new one:
Go ahead and select any template you like. We will examine the user interface at this point.
63
The map will be a live preview, showing the data that we imported into TileMill.
At this point, it is worth mentioning again that TileMill is not connected to any mapping
service and does not fetch live map data. What we see in the map is the data that we (or the
template) imported into TileMill.
In an ideal situation, we could open TileMill, zoom to a region of our choice, and be able
to see and style all the features, such as the roads and the buildings. Sadly, however, this
is not the case. What we import is what TileMill displays and allows us to style. Remember
that it displays the changes after we save the project, not at the moment that the import is
completed.
In the preceding screenshot, on the right-hand side is the CartoCSS editor, which displays a
huge chunk of code. Don't be afraid; once we understand how CartoCSS works, parsing and
understanding this code will be a piece of cake. CartoCSS is not as complex as a full objectoriented language. It's a matter of understanding some basic concepts and rules, that's all.
64
Chapter 3
On the left-hand side of the screen, you will see a dark gray area with some buttons aligned
vertically. Let's check them out one by one:
Editor: This is the first button; it brings you to the exact screen that you are currently
looking at.
Projects: This is the screen you saw when you first started TileMill. It is where you
select a template or your own project.
Manual: This is just a quick reference explaining the main functionality of TileMill.
Plugins: This allows you to download plugins with extra functionality, which will be
integrated directly into Mapbox.
Settings: This is where we set up everything ranging from where your projects are
saved, autoupdates, and other aspects of the application.
Let's head back to the Editor tab. In the lower-left corner of the screen, we will find another
group of buttonsthe Editing Tools. Let's start exploring them:
Templates is the first button. Here, we can define various aspects of the map that we
are styling.
The first option allows us to set up a legend, and we can use HTML and inline CSS to
design our legend as we like. We can also set up a teaser that shows upon hovering
or when tapping on a mobile device. Next, there is a full description tab, and in the
end, we can set up the location to which we can also add a link:
65
Fonts is the next button. TileMill opens a window and displays the full list of fonts
installed in the system. Using this section, you can easily copy the font name and
paste it into the editor. It's kind of hard to remember the full font name, so this
section is very helpful:
After Fonts, you will notice an icon that looks like curly brackets. This is a reference to
CartoCSS. This is the Carto button.
Do not underestimate this button! It will be your friend while learning CartoCSS!
Especially at the beginning, remembering all CartoCSS parameters will be difficult. Do
not be afraid to go into this section if you are looking for help:
66
Chapter 3
The last button is the Layers button. The most important functionality of TileMill lies
here as it gives you access to layers.
Each group of data that you import goes into a layer, and from this section, you can
add, edit, or delete your layers. There is also a layer data inspector to view the layer
data in a spreadsheet-like screen.
67
How to do it
Perform the following steps:
1. Download, or generate using GIS software, the map data required for the map.
2. Create a new TileMill project by clicking on New project.
3. Go to the Layers palette, click on Add Layer, and import the data into TileMill.
4. Style the map using CartoCSS.
68
Chapter 3
2. From the region of your choice, you will need two shapefiles. Download the
coastline shapefile and the osm2pgsql shapefiles. The first one is only the
coastline, and osm2pgsql shapefiles include everything else that we will need,
such as roads, building labels, and other features.
We have downloaded the San Francisco files for this example; if you want, you can
follow our example, but it really doesn't matter. Any region will do just fine.
3. Extract the ZIP files in a folder of your choice.
4. Each ZIP file will extract several files with extensions such as .dbf, .prj, .shx,
and .shp.
69
I will not go into a detailed explanation of how QGIS works, as it could be a book of its
own. For the purpose of this recipe, we just need to know how to navigate the map.
Clicking and dragging on the map area scrolls the map. We can use the scroll wheel
to zoom in or out.
70
Chapter 3
4. Click on the Open Attribute Editor icon in the toolbar. This will open a spreadsheettype editor, which displays all the attributes contained in this shapefile:
5. Observe the attributes, such as highway. We can see that it contains values such as
footway, path, residential, and so on. These are the attributes and values that we
will use in TileMill to style our map.
71
7.
In this dialog box, we can select the values we want in two ways. The first option is to
type the expression directly in the Expression section at the bottom of the screen.
The second option is to select the Fields and Values category in the Function list
section on the left-hand side and then double-click on the attribute that you are
interested infor example, highway. Note that the attribute appears in the expression
section at the bottom.
72
Chapter 3
11. Finally, click on the Select button and then on Close to close the dialog.
12. If you scroll to the attribute editor, you will notice that some rows are now selected;
these are all the rows where the highway attribute is equal to motorway. To view
the motorways highlighted in the map, click on the Zoom Map to the Selected Rows
button in the attribute editor toolbar. It's the one that looks like a magnifier. You can
also press Ctrl + J in Windows and Linux or Cmd + J on Mac.
13. Close the attribute editor, and you will see all the motorways highlighted in the map.
In case you do not understand what an attribute or value represents, head
over to http://wiki.openstreetmap.org/ and type the attribute
or value in the search box on the upper right-hand side. For example, you
can see all the values of the highway attribute that we just explored at
http://wiki.openstreetmap.org/wiki/Key:highway.
You have now learned a powerful way to inspect shapefiles and their attributes. If you are
in the GIS business, you probably already have this skill. If you are just a developer with the
ultimate purpose of creating the most beautiful maps in the world, then you may have never
encountered GIS software before.
I strongly encourage you to learn how to use QGIS or any other GIS software in this case.
There are many times that you may receive data from other sources in a non-standard format
with unknown attributes.
Without this type of software, it is extremely difficult to find which attribute represents which
feature on the map. Not having the capability to visualize shapefiles and find out what
features they contain is a huge drawback.
73
7.
74
Open Layers. You will see the #countries layer that was imported by TileMill
automatically. Leave it for now, and click on the Add layer button to add a new layer:
Chapter 3
8. In the Add layer dialog box, select Browse and browse to the location of the extracted
ZIP files. We will import the polygons first. My file is called san-francisco.osm.
polygon.shp; yours may be different depending on the area that you download, but
the filename will always end with polygons.shp.
9. Click on Done to browse the dialog box to return to Add layer. The next thing we will
need to do is specify an ID. TileMill set mine as sanfrancisco automatically, but as
I will import more layers, this ID won't make sense, and it's better to select something
more appropriate. It will help us separate it from the lines and layers containing other
datatypes. I will set my ID to sf-polygons for the San Francisco polygons. Finally, click
on Save:
In most cases, you won't need to adjust the SRS field. However, in case it fails,
we have to provide the correct value in this field.
Spatial Referencing System (SRS) is a quick way to identify a spatial
referencing system using the PROJ.4 syntax. There are several ways to get
the PROJ.4 string, but one of the easiest is by searching on http://www.
spatialreference.org/.
You can find the PROJ.4 string for WGS 84 at http://www.
spatialreference.org/ref/epsg/4326/proj4/, which is the following:
+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs
For more information regarding the PROJ.4 specification, visit http://trac.
osgeo.org/proj/.
75
Well, you are looking at hex values, and it is kind of difficult to decipher the colors just
by reading them.
Luckily, TileMill displays the colors used in CartoCSS in the color swatches at the
bottom of the screen. Clicking on a color swatch allows you to change this color using
a handy color picker.
76
Chapter 3
This is not the best way to build a color palette. Now is the perfect time to
talk about the tools that can help us build a really beautiful color scheme. We
want to design the most beautiful maps, after all!
One of the online tools we can use is Adobe Color (formerly, Adobe Kuler).
You can access it at https://color.adobe.com/, and it will help you
build your color scheme by selecting a color rule, such as monochromatic,
complimentary, triadic, compound, or even building a custom color palette.
We can save our color scheme and share it with the Adobe Color community,
as well as explore the color schemes designed by other people.
77
3. In order for TileMill to update the map, you will have to save, so ensure that you do
this by clicking on the Save button on the upper right-hand side of TileMill:
The keyboard shortcut to save is Ctrl + S for Windows and Cmd + S for OS X.
At this point, we should be able to see the styled coastline. If nothing is visible, open
Layers and click on the magnifier icon next to the coast. It will zoom to the region that
the coastline is in.
78
Chapter 3
Suppose you have an error in CartoCSS. In this case, TileMill will highlight
the line number in yellow and display an error message at the bottom of the
screen. Ensure that you fix all the errors and save again:
4. The next time we open the project, TileMill will not zoom automatically to the region
we are working with. It's a good time to do it now as we have styled the basic
coastline. Click on the Wrench icon in the upper right-hand side of the screen to go to
Project Settings.
5. You will probably see a blank dark blue map. Our region is there, but we are currently
at zoom level 1, and the whole world is visible. Using the zoom plus and minus
buttons and dragging around the map, try to find the region that you are working with.
6. When you zoom in to the region, shift and drag to enclose it in a rectangle. This
rectangle will define the area that we are working with and the one that TileMill will
eventually export the tiles of.
7.
Click on the center of the region, and a marker will appear. This is the center of our
project.
79
9. Back in the editor, let's style the roads. We will set the colors of all roads to yellow and
then use different line widths for different types of roads by executing the following
code:
// Set the colors of all roads to @street
#sf-lines[highway != ""]{
line-color: @streets;
}
// for motorways, and trunk set line width to 5
#sf-lines[highway="motorway"],
#sf-lines[highway="trunk"] {
line-width: 5;
}
80
Chapter 3
// for primary roads, set line width to 3.
#sf-lines[highway="primary"] {
line-width: 3;
}
// for secondary roads, set line width to 2
#sf-lines[highway="secondary"] {
line-width: 2;
}
// for paths roads, set line width to 1, and use dashes
#sf-lines[highway="path"] {
line-width: 1;
line-dasharray: 5, 3;
line-cap: round;
line-join: round;
}
81
In case you forget what features a layer contains, you can go to the Layers
palette and click on the icon that looks like a spreadsheet next to the layer's
name. TileMill displays a table with all the features of a layer and the values
that they contain:
11. If you try to zoom out now, you will notice that the streets are very dense with a lot
of detail at lower zoom levels. We will fix this next. Reduce the opacity of all roads to
0.45 when the zoom level is less than 16 through the following code:
[zoom < 16] {
#sf-lines[highway != ""] {
line-opacity: 0.45;
}
}
82
Chapter 3
12. Reduce the opacity of all roads to 0.25 when the zoom level is less than 14 with the
following script:
[zoom < 14] {
#sf-lines[highway != ""] {
line-opacity: 0.25;
}
}
13. Use this code to hide the roads when the zoom level is less than 12:
[zoom < 12] {
#sf-lines[highway != ""] {
line-opacity: 0;
}
}
14. When the zoom level is less than 16, set the line opacity to 1 by executing the
following code:
[zoom < 16] {
#sf-lines[highway =
#sf-lines[highway =
#sf-lines[highway =
#sf-lines[highway =
line-opacity: 1;
}
}
"motorway"],
"trunk"],
"primary"],
"secondary"],{
Remember that styles at the bottom overwrite the ones above them. So,
even if we set the opacity to 0.45 for zoom < 16 for all roads, motorways,
trunks, and primary and secondary roads, they will still have an opacity of
1. The rest will remain at the previous value.
15. When the zoom level is greater than 15, you can use the following code:
[zoom > 15] {
#sf-lines[highway="primary"]{
line-width: 10;
}
#sf-lines[highway = "secondary"] {
line-width: 8;
}
83
Great! Try to zoom in and out now and you will notice the difference. Observe how the
opacity of the roads reduces every time you zoom out and how certain features are
hidden.
16. Our map already looks great, but it doesn't have labels yet. A map without road
names will not be very popular! At the beginning of our style, directly below the
#coast styling, we have a section that sets all road colors to street colors. Execute
the following code:
#sf-lines[highway != ""]{
line-color: @streets;
}
17. Let's add the label style in this selector. Replace CartoCSS in the preceding section
with the following code. As we explained in the introduction, we forced TileMill to
redraw the elements in the current selector with double colons :: (road-label
is just a name we defined to remember what this redrawn part does). We will fetch
road names from the [name] column. The rest of CartoCSS just consists of various
typography attributes. We will also set text-placement to line, so the labels will
be aligned with the lines of the roads:
#sf-lines[highway != ""]{
line-color: @streets;
::road-label[zoom>15] {
text-name: [name];
text-size: 14;
text-fill: @text;
text-face-name: "Arial Bold";
text-halo-radius: 1;
text-halo-fill: @streets-dark;
text-placement: line;
}
}
84
Chapter 3
This is how it will look:
How it works
If you haven't installed Mapbox Studio yet, head over to the Mapbox website and download it
now from https://www.mapbox.com/mapbox-studio/.
It's available for all major platforms, and the installation is pretty straightforward. Once
installed, open the application and prepare for an interface tour!
85
86
Chapter 3
On the left-hand side, you will find the Save as, Settings, Layers, Fonts, and Docs buttons:
Save as: This saves the project. You have to save each new project you create to your
local hard drive.
Settings: This allows you to configure the project settings, such as the available zoom
levels and other parameters.
Layers: This shows all the layers available at the source(s) that you select when you
create the project.
Fonts: This opens a window with a preview and the font names of the typefaces
available for use in your maps.
Docs: This opens a window with reference both to the user interface of Mapbox
Studio and CartoCSS.
At the top of the window, there is a toolbar with some buttons. Let's check them out from
left to right:
Search: This allows you to search for a specific location on the map. Try a city
or country to quickly jump to that location.
Full screen map: This shows or hides the CartoCSS editor, showing the map in
full screen.
Inspector: This allows you to visualize all layer data contained in the sources.
In the far upper-right corner of the CartoCSS window, you will find the Export Image button. It
allows you to export images up to 600 ppi.
How to do it
Perform the following steps:
1. Create a new project in Mapbox Studio by clicking on Projects and then on + New
project.
2. In the New project window, select the sources to be used in the map. The source
could be one of the Mapbox ones, such as Mapbox Streets, Mapbox Terrain, or
Mapbox Satellite, or a combination of them.
3. Style the map using CartoCSS.
87
Styling a map
Perform the following steps:
1. Create a new project in Mapbox Studio. We will not use a template; we will start from
scratch. At the bottom of the New projects screen, you will see a Create button; next
to it, ensure that it's mapbox.mapbox-streets-v5, which means that Mapbox Streets
will be used as source.
Remember, we do not import data into Mapbox Studio as we do with TileMill; instead,
we will use the standard Mapbox sources provided to us. We can create our own
sources if we want, and we can combine multiple sources together to create more
complex maps.
For now, we will use just Mapbox Streets, so click on the Create button:
2. The editor will pop up with some basic imported CartoCSS. The first thing you will notice
is that the Save as button in the upper-right corner is highlighted in blue. This means
that the project is unsaved. We won't get far without saving, so let's do it right now.
88
Chapter 3
Click on the Save as button, select a location on your hard drive, name the project as
you want, and click on Save.
3. Zoom in to a region of your choice and clean up all the CartoCSS from the style. Hit
Save again (Ctrl + S for Windows and Cmd + S for Mac). You will notice that the map is
now blank. Don't worry, there is an awesome way to visualize data in Mapbox Studio.
4. Let's finish with the project setup first before we do this. Head over to Settings and
increase Maxzoom to 22.
5. Among the icons arranged on the topmost bar above the map is the Inspector icon. It
looks like layers with a magnifier on top. Click on it now.
The map now shows the data that the layer contains. If your zoom range is below 15,
the data may be dense, so ensure that you zoom in until you get a clear picture of
what's going on.
If you click on various lines, you will see that a popup appears, showing you
information such as the kind of layer, class, type, and name:
89
7.
Open Layers from the Mapbox Studio sidebar. You will see all the layer IDs available
in Mapbox Streets as we are using this source. Click on a layer ID to see what classes
it has; for example, click on #road, and you will see that it can be one of motorway,
motorway link, main, street, and so on.
8. We will begin by styling #water. First of all, set the background-color value,
which in this case actually represents the ground color, then style #water. Run the
following code:
Map {
background-color: @land;
}
#water {
polygon-fill: @water;
line-width: 1;
line-color: @outlines;
}
9. Click on Save when you have finished and inspect the map:
90
Chapter 3
10. Continue inspecting the layers and styling the IDs that you need one-by-one in the
same way that we did in TileMill. Here is the code for the complete style:
@water: #046380;
@some: #002F2F;
@land: #E6E2AF;
@outlines: #EFECCA;
@text: #A7A37E;
@green: #002F2B;
Map {
background-color: @land;
}
#water {
polygon-fill: @water;
line-width: 1;
line-color: @outlines;
}
/////////////////
/// ROADS ///
/////////////////
#road {
line-color: @text;
[type='motorway'], [type='motorway_link'] {
line-width: 6;
[zoom > 16] { line-width: 12 }
[zoom < 14] { line-width: 3 }
}
[type='main']
line-width:
[zoom > 16]
[zoom < 14]
}
{
5;
{ line-width: 8 }
{ line-width: 3 }
91
92
Chapter 3
Here's the final result:
There's more
In the previous section, you learned how you can use and style data provided by Mapbox.
Now, we will continue from there and take a look at how to import our own data into Mapbox
Studio.
93
2. Now, we need to add our layers. The data that a layer can contain can be a shapefile;
can be in the .kml, .geojson, .gpx, .csv, .tif, and .vrt formats; or can even
be PostGIS and SQLite databases.
We will use a shapefile that contains the national parks in US. You can download the
file from http://www.naturalearthdata.com/downloads/10m-culturalvectors/parks-and-protected-lands/. It's a ZIP file, so we will need to extract
it somewhere on the hard drive.
3. Back in Mapbox Studio, click on the Browse button in the Add a New Datasource
window, and select ne_10m_parks_and_protected_lands_area.shp from the files
that we extracted in the previous step.
94
Chapter 3
You will see that the shapefile has been imported correctly. Mapbox Studio now
shows us a preview, and we can already zoom and pan. You can even click on a
shape and a popup with the layer attributes will appear:
On the sidebar to the right, note that it correctly detected the projection and showed
it in PROJ.4, which is as follows:
+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs
You can add as many layers as you want in a single source and even a
mix of shapes, GeoJSON, and other file types.
4. You can rename the layer if you want. Click on the Rename button below the filename
at the top of the sidebar to the right. I named mine national_parks for simplicity.
5. Before uploading our own data to Mapbox, we need to save the project locally. Press
Ctrl + S on Windows or Cmd + S on OS X, choose a filename, and store it somewhere
on your hard drive.
6. Now that the project is saved, click on Settings and then on Upload to Mapbox.
Mapbox Studio will initiate the process to upload the data to your Mapbox account.
95
Once the upload is completed, you can find the Map ID above the Upload to Mapbox
button. Copy the Map ID; we will need it in a while.
8. That's all that's needed to create a new data source to be used in Mapbox Studio.
Now, we need to open the map from the previous recipe. If you didn't complete the
previous recipe, any of the sample projects will do just fine.
9. Once the project is open, click on Layers and then on Change Source. In the Sources
window, before the Apply button is the source that we will use for this map, which is
mapbox.mapbox-streets-v5.
10. We will need to append our own source, which we just created. We have the Map
ID already copied to the clipboard, so add a comma (,) and paste the Map ID. The
complete string should look similar to the following:
mapbox.mapbox-streets-v5, mapboxrecipes.62340c1c
11. Click on Apply. Our own custom datasource will be added to the project.
You can make sure of this by opening the Layers palette. Note that there is a
#national_parks layer here. This is our own data sourcethe layer that we added
earlier.
96
Chapter 3
12. In order to see the layer, we need to style it first. For this layer, paste the following
CartoCSS code at the bottom of the style:
#national_parks {
polygon-fill: @green;
opacity: 0.5;
text-name: [name];
text-size: 32;
text-fill: @text;
text-face-name: "Meta Offc Pro Bold";
text-halo-radius: 2;
text-avoid-edges: true;
text-halo-fill: @green;
[zoom < 7] {
text-size: 18;
}
}
13. Save the project and enjoy our custom data overlaid on the Mapbox Street map data:
97
How it works
First of all, we will export our maps from TileMill. The format that we will export in will be
.mbtiles, which is actually a SQLite file containing the data and the tiles.
MBTiles is just a SQLite database that contains metadata information along
with PNG images. Its purpose is to have a single file that contains everything
needed to serve a map. In cases such as mobile applications, storing
thousands of tiles and metadata information in the app container can be
difficult to manage and can be extremely poor in performance.
The following is a screenshot showing the tables of the SQLite database along
with the table of PNG files:
98
Chapter 3
Reading SQLite files directly in PHP is not performant at all, so we will use MBUtil to convert
them into PNG files. Next, we will use a PHP tile server developed by Petr Pridal. Developing
our own tile server is not a hard task, but it is beyond the scope of this book. Finally, we will
set up a simple project and serve the tiles.
How to do it
Perform the following steps:
1. Export MBTiles from TileMill by clicking on Export and choosing MBTiles as the
export option.
2. In Export Options, ensure that the zoom is configured and the center is within the
bounds of our map.
3. Click on Export, and once finished, click on Save to store MBTiles on the hard drive.
4. Convert the MBTiles (SQLite) files into regular PNG files using MBUtil.
5. Use one of the open source tile servers, such as the PHP tile server, to serve the
newly generated PNG files.
99
4. Click on Export to export your tiles. You will then be transferred to the export queue,
and you will be able to monitor the progress and the time remaining:
5. Once finished, click on the Save button. TileMill will show you the location on your
hard disk to find the exported MBTiles.
100
Chapter 3
It uses a folder for each zoom level, with each column being a subdirectory
and each tile in the column a file. The other common format used in maps
is TMS. You can read more about the XYZ format at http://wiki.
openstreetmap.org/wiki/Slippy_map_tilenames.
101
2. We will use tileserver-php. It's extremely simple to use, and the whole project is just a
single PHP file. Clone the project into the folder using the following command:
git clone https://github.com/klokantech/tileserver-php
3. Now, copy the exported folder from MBUtil into the same directory as the
tileserver.php file.
4. You can now access the tileserver.php file from a web browser at http://
localhost/tileserver.php:
That's it! We can now serve our maps from our own PHP server. Deploying the server is
extremely easy, and the only thing needed is to copy the files into the server. The best part is
that PHP is installed almost everywhere, and it is also very easy to find a cheap hosting service.
102
Chapter 3
Getting ready
TileStream requires Node.js v0.10.x or 0.8.x. It will not work with the most recent versions of
Node.js, so ensure that you have one of the preceding versions installed.
If you don't have Node.js installed yet, go ahead and install it. Ensure that you do not install
the latest build, but one of the versions required by TileStream.
How to do it
Perform the following steps:
1. Export the MBTiles file from TileMill by clicking on Export and selecting MBTiles as
the export option.
2. In Export Options, ensure that the zoom is configured and the center is within the
bounds of our map.
3. Click on Export, and once finished, click on Save to store the MBTiles file on the hard
drive.
4. Use any one of the open source Node.js tile servers, such as TileStream, to directly
serve MBTiles.
103
The dot (.) at the end clones it into the folder that we are in without creating a new
subfolder.
4. Once installed, ensure that the server is working. Start the TileStream server
by typing ./index.js.
5. Let's copy the .mbtiles file into a location that TileStream expects them to be in.
The default directory is ~/documents/MapBox/tiles.
6. Head over to a browser and type http://localhost:8888/ to access
TileStream. You can access the map of your choice directly using http://
localhost:8888/#!/map/SanFrancisco:
That's it! We now have our custom MBTiles file exported from TileMill and served by our own
Node.js server. You can use a hosting service that supports Node.js, such as Heroku, to deploy
your project.
104
www.PacktPub.com
Stay Connected: