Migration Guide for Stamen Map Tile Users¶
Stadia Maps has partnered with Stamen Design to host their iconic map styles. If you are currently accessing Stamen map tiles via the Fastly CDN or a Stamen domain, you'll need to make a few (small!) changes to keep on using these maps after August 31, 2023. After this point, we will start progressive brownouts before the old URLs stop working entirely on October 31, 2023.
The typical migration for a web-based map should take about ten minutes. In most cases you'll only need to touch 2 or 3 lines of code. Let's dive in!
Create a Stadia Maps account¶
No credit card is required to create an account, and we offer a free tier for non-commercial users. Commercial and higher-volume plans start at just $20/month. If you have any questions about pricing or aren't sure which plan you need, contact us via email at support@stadiamaps.com.
Once you create an account, the onboarding flow will walk you through setting up domain authentication or an API key. After entering your domain or generating an API key, you're ready to migrate! If you are using the Stamen URLs directly, proceed to our URL-based migration steps. Otherwise, find your framework under the next section.
Toner Hybrid Deprecation Notice
Note that the Toner Hybrid style is no longer available in raster form. You can recreate this by combining the lines and labels layer groups. Additionally, you may find that you can achieve the same (or better!) by migrating your application to the Toner vector styles and using only the layers you need.
URL-based migration steps¶
Switch your tile URLs¶
If you are using the URLs directly (for example, in Leaflet via an L.tileLayer
),
find your style in the table below and copy the new URL format string. Leaflet users can
copy this directly into the L.TileLayer
URL configuration. Other map renderers
typically use a similar URL format.
Style URLs¶
What do {x}, {y}, {z}, and {r} mean?
The {x}
, {y}
, and {z}
placeholders represent x, y, and zoom
following the standard slippy map tilename
convention. This format is used by most popular libraries. Note that our tile numbering uses the XYZ
scheme, not TMS.
The {r}
placeholder is used for HiDPI ("retina") display suppoort. Popular web map renderers like Leaflet
understand this placeholder. If your renderer does not understand this (e.g., MapLibre GL JS or QGIS),
you can either remove the placeholder to get raw 256x256 PNGs, or replace it with @2x
for 2x scaled images.
Here is a translation table of the primary map styles with all cartographic layers present. Simply change your URLs in Leaflet, OpenLayers, or your other raster map renderer of choice.
Tip
If you'd like to use an API key instead of domain auth, simply append ?api_key=YOUR-API-KEY
to the URLs above.
Stamen identifier | Stadia URL format | Notes |
---|---|---|
toner |
https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}{r}.png |
|
toner-lite |
https://tiles.stadiamaps.com/tiles/stamen_toner_lite/{z}/{x}/{y}{r}.png |
|
terrain |
https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}{r}.png |
|
watercolor |
https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg |
JPEG only; not available in @2x resolution |
Layer Group URLs¶
We also have a migration path for Stamen's "flavors" containing a subset of the cartographic layers in the full style.
Stamen identifier | Stadia URL format | Notes |
---|---|---|
toner-background |
https://tiles.stadiamaps.com/tiles/stamen_toner_background/{z}/{x}/{y}{r}.png |
Includes only background layers (water, landcover, etc.) and lines (roads, borders, etc.) |
toner-lines |
https://tiles.stadiamaps.com/tiles/stamen_toner_lines/{z}/{x}/{y}{r}.png |
Includes only line layers (road, borders, etc.) |
toner-labels |
https://tiles.stadiamaps.com/tiles/stamen_toner_labels/{z}/{x}/{y}{r}.png |
Includes only label layers (places, road names, etc.) |
toner-hybrid |
Deprecated. You can recreate toner-hybrid by combining the labels and lines layer groups or using vector styles |
|
terrain-background |
https://tiles.stadiamaps.com/tiles/stamen_terrain_background/{z}/{x}/{y}{r}.png |
Includes only background layers (water, landcover, hillshading, etc.) |
terrain-lines |
https://tiles.stadiamaps.com/tiles/stamen_terrain_lines/{z}/{x}/{y}{r}.png |
Includes only line layers (road, borders, etc.) |
terrain-labels |
https://tiles.stadiamaps.com/tiles/stamen_terrain_labels/{z}/{x}/{y}{r}.png |
Includes only label layers (places, road names, etc.) |
Updating attribution¶
Finally, you'll need to update your attribution to include Stadia Maps and (for all styles except Watercolor) OpenMapTiles. In HTML, the full attribution looks like this.
© <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a>
© <a href="https://stamen.com/" target="_blank">Stamen Design</a>
© <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a>
© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>
Leaflet example: Bringing it all together¶
Here's an example of how to update a Toner Lite map to the new URL in Leaflet.
- L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}{r}.png', {
+ L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_toner_lite/{z}/{x}/{y}{r}.png', {
maxZoom: 19,
- attribution: 'Map tiles by <a href="https://stamen.com/">Stamen Design</a>, Data by © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> under <a href="http://www.openstreetmap.org/copyright">ODbL<a/>',
+ attribution: '© <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> <a href="https://stamen.com/" target="_blank">© Stamen Design</a> © <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> © <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>',
}).addTo(map);
Migration steps for other integrations¶
We are working with major plugins and library authors to transition to the new URLs, and will update this guide as updates are available. Send us an email if you have any questions.
contextily¶
We are working to prepare a pull request to update the URLs for the Stamen map styles. In the meantime, you can update your code to directly call the new URLs, along with your API key.
Here is an example script:
import geopandas
import geodatasets
import contextily as cx
df = geopandas.read_file(geodatasets.get_path("nybb"))
ax = df.plot(figsize=(10, 10), alpha=0.5, edgecolor="k")
- cx.add_basemap(ax, crs=df.crs, source=cx.providers.Stamen.Terrain)
+ cx.add_basemap(ax, crs=df.crs, source='https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}{r}.png?api_key=YOUR-API-KEY')
folium¶
folium has built in references for some tile styles, however, the new Stamen URLs are not available. To access these, you can utilize the xyzservices library.
If you use Domain Authentication, you can simply reference the appropriate style and you should be all set. If you are
using API keys, you will also need to append the api_key
variable to the URL.
The code below is for Stamen Toner and uses the API key authentication method:
import folium
import xyzservices.providers as xyz
m = folium.Map(location=[39.7684, -86.1581], zoom_start=12)
#Add the Stadia Maps Stamen Toner provider details via xyzservices
tile_provider = xyz.Stadia.StamenToner
#Update the URL to include the API key placeholder
tile_provider["url"] = tile_provider["url"] + "?api_key={api_key}"
#Create the folium TileLayer, specifying the API key
folium.TileLayer(
tiles=tile_provider.build_url(api_key='YOUR-API-KEY'),
attr=tile_provider.attribution,
name=tile_provider.name,
max_zoom=tile_provider.max_zoom,
detect_retina=True
).add_to(m)
folium.LayerControl().add_to(m)
m
GeoLayers¶
The team behind GeoLayers have recorded a video demonstrating how to continue using the Stamen map styles with Stadia Maps.
Licensing for Commercial Use
Please contact sales@stadiamaps.com for licensing information and a quote if you are using our maps for commercial use. For non-commercial (including academic) use, no special permission or licensing is necessary for these projects. See our FAQ for details.
ggmap¶
As of ggmap
version 4.0.0, it's (still!) easy to use the Stamen basemaps.
You can check your current version by typing the following code into your R console.
packageVersion("ggmap")
If it is less than 4.0.0, you'll need to upgrade.
Using Stamen Watercolor? Follow these steps first!
There is currently a bug
in the released version of ggmap
with the Stamen Watercolor style.
If you are using this style, follow these steps before proceeding:
-
Remove the existing version of ggmap from your environment.
remove.packages("ggmap")
-
Install the
devtools
package in your R environment.install.packages("devtools")
-
Install the patched version from GitHub.
devtools::install_github("stadiamaps/ggmap")
Next, before you draw any plots, you need to register your API key.
register_stadiamaps("YOUR-API-KEY-HERE", write = TRUE)
For a one-off visualization in an ephemeral environment,
or if you are working on a shared computer,
omit the write
argument.
In other cases, we recommend leaving it.
This saves the API key to your .Renviron
file (usually in your home directory),
which is automatically loaded when starting most new R sessions.
This way you don't need to keep keys in your source code.
Then, it's just a matter of changing a few lines of code!
First, any Stamen styles have slightly different names.
Stamen styles will have all -
characters replaced with an _
.
Additionally, you'll need to add a stamen_
prefix.
Bringing it all together, toner-lite
would become stamen_toner_lite
.
You can find the style identifiers on each of our map styles pages.
If you were using the get_stamenmap
function,
this has been renamed to get_stadiamap
.
Other functions like qmplot
remain unchanged,
but don't forget to update the parameters with the new style identifiers.
Here are some examples.
- get_stamenmap(bbox, zoom = 5, maptype = "toner-lite") %>% ggmap()
+ get_stadiamap(bbox, zoom = 5, maptype = "stamen_toner_lite") %>% ggmap()
- qmplot(lon, lat, data = earthquakes, maptype = "toner-lite", geom = "density2d", color = I("red"))
+ qmplot(lon, lat, data = earthquakes, maptype = "stamen_toner_lite", geom = "density2d", color = I("red"))
Knight Lab StoryMapJS¶
If you have an existing storymap, you'll need to follow the directions on their updated basemap page. After signing up for your account, follow the instructions to add an API key and select your preferred style.
Leaflet in R¶
If you are using the R implementation of Leaflet
or a tool that builds on it like Shiny Apps,
update to the latest version of Leaflet Providers and use the new provider name.
Everything has been migrated under the Stadia provider, and we've added a Stamen prefix.
For example, Stamen.Terrain
becomes Stadia.StamenTerrain
.
library(leaflet)
leaflet() |>
setView(lng = -71.0589, lat = 42.3601, zoom = 12) |>
addTiles() |>
addProviderTiles("Stadia.StamenTerrain")
Note that this approach works inside RStudio, for localhost
development, and with domain-based auth.
If you are deploying in a situation where you can't use domain auth, you'll need to use an API key.
You can do this with the addTiles
method and a URL template directly like so:
library(leaflet)
map <- leaflet() %>%
addTiles(
urlTemplate = "https://tiles.stadiamaps.com/tiles/{variant}/{z}/{x}/{y}{r}.png?api_key={apikey}",
attribution = paste('© <a href="https://stadiamaps.com/" target="_blank">Stadia Maps</a> ' ,
'© <a href="https://stamen.com/" target="_blank">Stamen Design</a> ' ,
'© <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> ' ,
'© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>'),
options = tileOptions(variant='stamen_toner_lite', apikey = 'YOUR-API-KEY')
) %>%
fitBounds(lng1 = -86.1581, lat1 = 39.7684, lng2 = -87.1581, lat2 = 40.7684)
map
Leaflet providers¶
Leaflet Providers has support for the Stamen Styles from Stadia Maps since version 2.0.0. If you are using Leaflet Providers directly, you will need to change your style name slightly. The styles have all moved under the Stadia provider, and the style name has been prefixed with Stamen. For example:
- L.tileLayer.provider('Stamen.Watercolor').addTo(map);
+ L.tileLayer.provider('Stadia.StamenWatercolor').addTo(map);
You can see the full list of available style identifiers on the Leaflet Providers preview site.
Little Navmap¶
Little Navmap has a patch ready that will include the Stamen style URLs. If you are seeing warning tiles, you can follow the steps in this GitHub issue to resolve the issue today. The next release will include a permanent fix.
Maps Marker Pro¶
Maps Marker Pro supports Stadia Maps since version 4.27. You can upgrade to get access to the new Stadia-hosted styles by Stamen. Maps Marker has a full walkthrough of the setup process on their website.
Mapster WP Maps¶
In order to utilize the new Stamen map tiles, you will need to add a Custom Style JSON to your instance. You can follow our guide to accomplish this.
OpenLayers¶
If you were previously using the Stamen
source in your application, update to the
StadiaMaps
source instead after upgrading OpenLayers v8.0.0 or higher.
Here is an example of switching a map that had the Stamen Watercolor style and the terrain labels layer.
import Map from 'ol/Map.js';
-import Stamen from 'ol/source/Stamen.js';
+import StadiaMaps from 'ol/source/StadiaMaps.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
const map = new Map({
layers: [
new TileLayer({
- source: new Stamen({
- layer: 'watercolor',
+ source: new StadiaMaps({
+ layer: 'stamen_watercolor',
+ // apiKey: 'OPTIONAL' (we suggest domain-based auth)
}),
}),
new TileLayer({
- source: new Stamen({
- layer: 'terrain-labels',
+ source: new StadiaMaps({
+ layer: 'stamen_terrain_labels',
+ // apiKey: 'OPTIONAL' (we suggest domain-based auth)
}),
}),
],
Still using an older version? No worries. You can reference the tiles directly by URL in an XYZ source. Our OpenLayers tutorial shows you how.
xyzservices compatible libraries¶
If you are using a xyzservices compatible Python environment, you can reference the new Stamen tile URLs easily. A full list for Stadia Maps can be found in their docs.
After you specify the provider and variant, you should be all set if you are using Domain Authentication.
If you need to utilize an API key, you must modify the base URL to include the key. We'll use Stamen Toner in the example below:
provider = xyz.Stadia.StamenToner(api_key="<insert api_key here>")
provider["url"] = provider["url"] + "?api_key={api_key}" # adding API key placeholder
We're here to help¶
At Stadia Maps, real human support is part of our DNA. If you have any questions or need further assistance with your migration, send us an email.