Custom Map Styling¶
Want to change the look and feel of the map? Custom styles allow you to change the color scheme of an existing style, change the language of place labels, and more.
Vector Maps¶
One major benefit to vector map tiles is that you can change the style to suit your liking (even dynamically!). Our vector tiles are compatible with the popular OpenMapTiles schema, and these base layers can be styled to fit a wide range of use cases.
MapLibre styles are the most common method of styling vector tiles. Other renderers such as OpenLayers and Tangram have their own styling tools as well, but we'll only cover GL JSON styles here as they are the most widely used. You can use these styles on the web via MapLibre GL JS, and on mobile via either MapLibre Native or Flutter MapLibre GL.
Modifying an Existing MapLibre Style¶
Tip
You are free to modify all Stadia Maps Styles for your own applications. For specific details per-style, check out our attribution page.
We recommend using Maputnik, an open-source style editor, to create and edit GL JSON styles. The easiest way to get started is by selecting "Open" from the Maputnik menu bar, entering the JSON URL for one of our styles, and customizing it to your liking.
Hosting or Bundling your Custom Style¶
Once you're happy with the result, you'll need to host the style somewhere: either on the web (your server, CDN, etc.) or bundled with your app.
Now all you have to do is load your custom style (URL or embedded JSON) instead of ours! (If you don't already have a map in your website or app, check out our documentation on maps for web or mobile, desktop & multi-platform apps).
Tip
If your custom style will be accessing our tiles with an API key (for example, in a mobile app),
you need to include your API key in the style. Specifically it will need to be added to any Stadia Maps
sources, such as the openmaptiles.json
URL under sources
. Simply add the api_key
as a query parameter
like this: https://tiles.stadiamaps.com/data/openmaptiles.json?api_key=YOUR-API-KEY
.
You can either edit the JSON directly, or go to the Data Sources view in Maputnik to edit the URL.
Advanced: Starting from Scratch or Porting from Another Vendor¶
If you're starting from another vendor, the first thing you'll need to know is what schema their vector tiles follow. For OpenMapTiles sources, then things should more or less "just work." For others, you will need to figure out how to map between their schema and the OpenMapTiles schema on your own. We also offer global elevation and other datasets via our additional data tilesets page, where you can find documentation and URLs.
Below you'll find a skeleton on which to build your own style, pre-filled with the URLs for our OpenMapTiles source,
sprites (you can substitute alidade_smooth
for any of our map styles), and glyphs (fonts). If you
need custom sprites and glyphs, the following sections give an overview of what you'll need.
Tip
If you are not using domain-based auth (ex: for a mobile app),
you will need to add an API key to the OpenMapTiles URL query string:
https://tiles.stadiamaps.com/data/openmaptiles.json?api_key=YOUR-API-KEY
If you need to always use EU servers for regulatory reasons, change the host to tiles-eu.stadiamaps.com
.
See EU Endpoints for more info.
{
"sources": {
"openmaptiles": {
"type": "vector",
"url": "https://tiles.stadiamaps.com/data/openmaptiles.json",
"attribution": "© Stadia Maps © OpenMapTiles © OpenStreetMap"
}
},
"sprite": "https://tiles.stadiamaps.com/styles/alidade-smooth/sprite",
"glyphs": "https://tiles.stadiamaps.com/fonts/{fontstack}/{range}.pbf",
"layers": [...]
}
Advanced: Customizing Sprites¶
You can generate your own sprite files using Spreet, and host them on your server/CDN.
Then, add them to your JSON style (using the sprite
key).
Note that (as in the example JSON above) you should not include the suffix or extension in the URL. For example,
if your output base name is sprite
, you would use the following URL in the JSON style
https://my-domain.com/path/to/sprite
. Mapbox/MapLibre will then request https://my-domain.com/path/to/sprite.json
and https://my-domain.com/path/to/sprite@2x.png
respectively (@2x
being appended automatically for retina/HiDPI
displays).
Advanced: Customizing Fonts¶
In our own themes, we have rolled up our default font into a "super-font" stack with the fallback order we want. This makes themes easier to edit, and we've listed them in the Stadia font families section below.
Stadia font families
- Stadia Regular
- Stadia Italic
- Stadia Bold
- Stadia Semibold
If you want to change the fallback order or remove specific fonts, you can mix and match from the full list below (collapsed).
Full individual font list
- Noto Sans Arabic Light
- Noto Sans Arabic Medium
- Noto Sans Arabic Regular
- Noto Sans Armenian Light
- Noto Sans Armenian Medium
- Noto Sans Armenian Regular
- Noto Sans Ethiopic Light
- Noto Sans Ethiopic Medium
- Noto Sans Ethiopic Regular
- Noto Sans Georgian Light
- Noto Sans Georgian Medium
- Noto Sans Georgian Regular
- Noto Sans Hebrew Light
- Noto Sans Hebrew Medium
- Noto Sans Hebrew Regular
- Noto Sans JP Light
- Noto Sans JP Medium
- Noto Sans JP Regular
- Noto Sans Light
- Noto Sans Medium
- Noto Sans Regular
- Noto Sans SC Light
- Noto Sans SC Medium
- Noto Sans SC Regular
- Noto Sans TC Light
- Noto Sans TC Medium
- Noto Sans TC Regular
- Noto Sans Thai Light
- Noto Sans Thai Medium
- Noto Sans Thai Regular
- Open Sans Bold
- Open Sans Italic
- Open Sans Regular
- Open Sans Semibold
- Roboto Bold
- Roboto Condensed Italic
- Roboto Italic
- Roboto Medium
- Roboto Regular
- SeoulNamsan B
- SeoulNamsan L
- SeoulNamsan M
As with sprites, if you want to use your own set of fonts, you will need to host these yourself.
Warning
Make sure that you are in compliance with any font licensing requirements before deploying maps with additional fonts.
You can use a tool like our own open-source
build_pbf_glyphs
CLI utility
or MapLibre FontMaker to generate the
SDF font glyphs. You will then need to update glyphs
key in your style JSON accordingly.
The text-font
property in a MapLibre Style
is a list which specifies fonts in fallback order. This is quite handy, but introduces some
complexity. We'll cover both approaches briefly.
Combining Glyphs Upfront¶
The easiest option is to never specify more than a single font in any font list. Then you can
host your font glyphs in a directory of static files (as generated by build_pbf_glyphs
).
You can still have fallback fonts without any extra complexity server-side by
combining glyphs upfront into "super fonts."
For example, you can roll up Latin script bold font and a Japanese bold font into a
single "bold" font. Let's call this "MyFont Bold." You just need to specify the fonts and a fallback order
(much as you would in the MapLibre style JSON). You can then
reference "MyFont Bold" in your style, and host the glyphs for MyFont Bold in a directory of static files.
Refer to the build_pbf_glyphs
README
for usage instructions.
Combining Glyphs Dynamically¶
If you need to handle fallback fonts dynamically via a list in your style, your server
will need to know how to handle Mapbox-style fontstack requests. These combine requests for
multiple fonts into a long URL. Your server software needs to select
the glyphs in given fallback order. We have open-sourced the Rust crate, pbf_font_tools
,
that we use ourselves (also as part of build_pbf_glyphs
). If you're using Node.js,
have a look at glyph-pbf-composite, which can be integrated
into most server stacks.
Raster Maps¶
Most customers ask us about raster tiles because they are using Leaflet. If that describes you, we have good news! Most Leaflet use cases for custom styles can be addressed with the maplibre-gl-leaflet plugin, which lets you render vector tiles inside Leaflet. Check out our example repository to see Leaflet in action with a custom style.
If you are still sure that you need raster tiles or static maps for your custom style, contact us for a quote.
Further Reading¶
The MapLibre Style Specification is the final authority on MapLibre styling. Even if you primarily use Maputnik for editing styles visually, this is still useful to have as a reference.