DEV Community

Cover image for MapLibre GL Vector Tiles with TMaps: Dark Mode and 3D
Tmaps Tunisia
Tmaps Tunisia

Posted on

MapLibre GL Vector Tiles with TMaps: Dark Mode and 3D

Raster tiles are pictures of the map. They're simple and they work everywhere, but what you get is what you get. Vector tiles send the map data itself (roads, buildings, labels) and let the browser draw it. That means the map stays sharp on any screen, zooming is smooth, you can rotate and tilt it, and you can restyle it instantly.

In this post we'll use TMaps vector tiles with MapLibre GL JS, the open-source WebGL map library, and build a little style switcher with four styles.

Live demo: examples.tmaps.tn/03-vector-maplibre-styles

MapLibre demo with the style switcher

How TMaps vector tiles work

You don't request the tiles yourself. Each style is a JSON document that follows the Mapbox Style Specification:

https://tiles.tmaps.tn/v-tile/{style}.json?api_key=YOUR_API_KEY
Enter fullscreen mode Exit fullscreen mode

That JSON lists the tile sources, the fonts (glyphs), the icons (sprites) and how every layer should be drawn. MapLibre reads it and fetches the rest on its own. There are four styles to choose from:

Style Good for
streets Everyday reference map, easy to read streets and points of interest
dark Dashboards and night mode
terrain Relief, rivers and topography
sunny Tourism and retail, warmer colours

1. A first vector map

You'll need a TMaps API key from the TMaps console, with your domain (and localhost) in its Authorized Domains.

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Vector map of Tunisia</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/maplibre-gl.css">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/maplibre-gl.js"></script>
  <style>
    html, body, #map { height: 100%; margin: 0; }
  </style>
</head>
<body>
  <div id="map"></div>
  <script>
    const API_KEY = 'YOUR_API_KEY';

    const map = new maplibregl.Map({
      container: 'map',
      style: `https://tiles.tmaps.tn/v-tile/streets.json?api_key=${API_KEY}`,
      center: [10.1815, 36.8002], // Tunis, as [lng, lat]
      zoom: 12,
      maxZoom: 18,
    });

    map.addControl(new maplibregl.NavigationControl(), 'top-right');
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

One thing to watch: MapLibre takes [longitude, latitude], the opposite of Leaflet's [lat, lng]. Mixing them up is the most common reason a map opens in the middle of the ocean.

TMaps streets style

2. Switch styles without reloading the map

map.setStyle(url) swaps the style but keeps the map, its position and its controls. A basic switcher is only a few lines:

const styleUrl = (name) => `https://tiles.tmaps.tn/v-tile/${name}.json?api_key=${API_KEY}`;

for (const name of ['streets', 'dark', 'terrain', 'sunny']) {
  const button = document.createElement('button');
  button.textContent = name;
  button.addEventListener('click', () => map.setStyle(styleUrl(name)));
  document.body.append(button);
}
Enter fullscreen mode Exit fullscreen mode

Here's the same view of Tunis in the other three styles. First dark, which works well on dashboards:

TMaps dark style

Then terrain:

TMaps terrain style

And sunny:

TMaps sunny style

Follow the user's dark mode

Since switching is instant, you can simply follow the operating system's theme:

const dark = window.matchMedia('(prefers-color-scheme: dark)');
const applyTheme = () => map.setStyle(styleUrl(dark.matches ? 'dark' : 'streets'));

dark.addEventListener('change', applyTheme);
applyTheme();
Enter fullscreen mode Exit fullscreen mode

3. Tilt and rotate

The map is drawn with WebGL, so you can tilt and rotate it, which raster tiles simply can't do:

map.jumpTo({
  center: [10.179, 36.799], // Medina of Tunis
  zoom: 15.5,
  pitch: 60,     // tilt, in degrees
  bearing: -25,  // rotation, in degrees
});
Enter fullscreen mode Exit fullscreen mode

Medina of Tunis tilted at 60 degrees

Users can do the same thing themselves with a right-click drag on desktop, or two fingers on a phone.

4. Customize a style

The style JSON is yours to tweak. Download it, change the layers (colours, fonts, which labels show up at which zoom), and host your own copy. Just keep two things in mind:

  • the tile URLs in sources must still point to tiles.tmaps.tn with your api_key, because that's how your usage is authenticated;
  • you're free to change layers, and also glyphs and sprite if you host your own fonts and icons.

Raster or vector?

Raster Vector
Libraries Leaflet, OpenLayers, any XYZ client MapLibre GL JS, MapLibre Native
High-density screens Blurry (no @2x yet) Always sharp
Changing the style Needs new tiles Instant, in the browser
Rotate and tilt No Yes
Older devices Very light Needs WebGL

For a simple map embedded in a page, raster tiles with Leaflet are hard to beat (that's the first post of this series). When the map is the heart of your product, go vector.

Going further

Questions or feedback? Leave a comment or write to [email protected].

Top comments (0)