The search for tiles: adventures in mapmaking with Stamen Toner, OSM and the German Federal Agency for Cartography
🗺️ All I want is a tileset that's free to use and grayscale
To make an online map, you just need two things: 1. the actual geographic things you want to display and 2. the background tileset.
To make my map of collectible space invader mosaics, I needed the locations of each piece:
and then, something to draw the locations on top of: the background tiles. (As we can see above, the map is decidedly not useful without the background :)!)
First love: Stamen Toner
For the first version of the map I used the beautiful high-contrast black-and-white tileset called Stamen Toner.
My invader map is used to help collecting the mosaics in the real world via an AR smartphone app. I want the markers to be prominent, everything else should be tuned out. Stamen Toner’s simplified black&white look worked great for this.
This tileset would be both the beginning and the end of the story, if not for one catch: it’s a commercial tileset, hosted by Stadia Maps and offered on a subscription plan. (I’m not affiliated with Stadia Maps and I’m not getting any incentive to write about them.)
Stadia Maps does provide a free tier (🙌), but I quickly exhausted it the day I posted the map on Hacker News. Actually, this is how I learned that the map made it to the front page:
I then bought a paid subscription in the 20 USD/month “starter” tier. Initially I intended to stick with it, but as the map gained more adoption, it outgrew the 20 USD plan. By April, I was fully using the million tiles / month included in the plan:
The next tier was 80 USD/month, which starts to be a lot for a hobby project with no income. Let’s look for something free!
Hallo Welt!
The best site I found for browsing tilesets is the demo gallery of the LeafletJS project. (LeafletJS is the JavaScript library I use to manage and display the map.)
I went through all of the options there with just two criteria in mind: 1. free to use and 2. black&white or grayscale, to preserve the distraction-free aesthetics of the map.
The choice was easy because I found only one tileset that met the criteria: WMS TopPlusOpen gray tileset, generously provided by the German Federal Agency for Cartography and Geodesy (Bundesamt für Kartographie und Geodäsie).
This tileset works fine. Maybe it has too much of a retro roadmap look, but it wasn’t a deal breaker.
What was a deal breaker, was that it turned out it had uneven tile coverage at different zoom levels in different geo areas. In Europe you could zoom in everywhere. But in other areas the tiles at close zoom levels were missing.
Here’s Hong Kong at zoom level 13:
and here’s zooming in at the port area (zoom level 16). The more Winnie the Pooh was zooming in, the more the tiles were not in the honey jar.
OpenStreetMap
Back to the drawing board. How do people make online maps anyway? It seems the most popular free tilest is the one provided and hosted by OpenStreetMap. The only issue is that it’s in color:
What if we took those tiles and re-painted them into grayscale on the client side?
leaflet-grayscale is a tiny hacky plugin that’s doing literally that, repainting each pixel one-by-one. It works, but it slows down the map. Also, the tiles are first displayed and then repainted, creating visual flicker.
But then, hey maybe we can just use CSS? LeafletJS helpfully allows us to apply any CSS class name to the tiles being displayed:
tile_layer = L.tileLayer(
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
{ "attribution": '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
"className": "paint-it-gray",
}
);
So we can then define the class as:
.paint-it-gray {
filter: grayscale(100%);
}
and just like that, it works:
We’re using the OSM tiles (available for free thanks to OpenStreetMap) and they are displayed in grayscale. The visual transformation to grayscale is done on the client using pure CSS, much more efficiently than the pixel-by-pixel method using the JS plugin.
And the Hong Kong port is right there, displaying at all zoom levels:
Third time’s the charm, I think I will stick with this one for a while :).
Credits
Kudos to Stadia Maps for offering a free tier and for having a very clear and friendly onboarding flow.
Kudos to LeafletJS for making such a hackable/customizable library
Kudos to OpenStreetMap for providing the free tiles that power so much of the indie mapmaking we see on the web
In other news
We reached 150 subscribers 🥳! Thank you for being a part of it :)
Postcard from Paris
Canal de St Denis north of Paris. I caught a few Space Invader mosaics along the way 💫.
Here’s to more sunny days ahead,
– Przemek
this is amazing! how can we load one city map onto google maps ? I right click but doesnt give me option of coordinates only to Mark as Flashed or to Take a peek. I am travelling to Rome next week and excited to flash some Invaders. thanks so much
OpenStreetMap tile server terms of use are available at https://operations.osmfoundation.org/policies/tiles/