---
title: "How to display an MVT layer of POIs and show a tooltip in Deck.gl | Deck gl | JavaScript maps SDK"
description: "Display MVT POI layers with tooltips in Deck.gl."
---

> For AI agents: a documentation index is available at [/llms.txt](https://docs.maptiler.com/llms.txt). Markdown versions of all pages are available by appending .md to any URL.

# How to display an MVT layer of POIs and show a tooltip in Deck.gl

This example demonstrates the process of loading an MVT layer of Points of Interest (POIs) using Deck.gl and displaying a tooltip. The specific layer showcased in this example is the `poi` layer that comes from the [MapTiler Planet tileset](https://docs.maptiler.com/schema/planet/#poi). You can easily implement this functionality by utilizing the code provided below the map.

In this case, the POIs within the layer are visually represented based on the `class` field.

Hold down the shift key to rotate the map. Move the cursor over the points to see their information

### NPM module setup

```bash
npm install --save @maptiler/sdk deck.gl chroma-js
```

#### main.js

```js
import { Map, MapStyle, config, Popup } from '@maptiler/sdk';
import '@maptiler/sdk/dist/maptiler-sdk.css';
import { MapboxOverlay } from '@deck.gl/mapbox';
import { MVTLayer } from '@deck.gl/layers';
import chroma from 'chroma-js';

config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';

const getPoiColor = (poi_class) => {
  const pois_class = {
    poi_shopping: chroma("#66C5CC").rgb(),
    poi_culture: chroma("#F6CF71").rgb(),
    poi_food: chroma("#F89C74").rgb(),
    poi_education: chroma("#DCB0F2").rgb(),
    poi_healthcare: chroma("#87C55F").rgb(),
    poi_public: chroma("#9EB9F3").rgb(),
    poi_sport: chroma("#FE88B1").rgb(),
    poi_station: chroma("#C9DB74").rgb(),
    poi_tourism: chroma("#8BE0A4").rgb(),
    poi_transport: chroma("#B497E7").rgb(),
    poi_accommodation: chroma("#D3B484").rgb()
  }
  return pois_class[poi_class] ? pois_class[poi_class] : chroma("#B3B3B3").rgb();
}

const map = new Map({
  container: 'map', // container id
  style: MapStyle.BASE, // style URL
  center: [-73.9843, 40.7536], // starting position [lng, lat]
  zoom: 15.5, // starting zoom
  pitch: 0
});

// Create a popup, but don't add it to the map yet.
const popup = new Popup({
  closeButton: false,
  closeOnClick: false,
  className: 'tooltip'
});

map.on('load', () => {
  const deckOverlay = new MapboxOverlay({
    interleaved: false,
    layers: [
      new MVTLayer({
        data: `https://api.maptiler.com/tiles/v4/{z}/{x}/{y}.pbf?key=${config.apiKey}`,
        loadOptions: {
          mvt: {
            layers: ['poi_shopping', 'poi_accommodation', 'poi_culture', 'poi_food',
              'poi_education', 'poi_healthcare', 'poi_public', 'poi_sport', 'poi_station',
              'poi_tourism', 'poi_transport']
          }
        },
        minZoom: 0,
        maxZoom: 15,
        radiusMinPixels: 6,
        radiusMaxPixels: 10,
        getPointRadius: 6,
        getLineColor: [255, 255, 255],
        getFillColor: f => {
          return getPoiColor(f.properties.layerName)
        },
        getLineWidth: 1,
        lineWidthMinPixels: 1,
        pickable: true,
        onHover: info => {
          if (info.picked) {
            popup.setLngLat(info.coordinate).setHTML(`<h4>${info.object.properties.name || ""}</h4><div>${info.object.properties.class}</div>`).addTo(map);
          } else {
            popup.remove();
          }
        }
      })
    ]
  });

  map.addControl(deckOverlay);
});
```

#### index.html

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="robots" content="noindex" />
    <title>How to display an MVT layer of POIs and show a tooltip in Deck.gl | NPM example</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div id="map"></div>
    <script type="module" src="./main.js"></script>
  </body>
</html>
```

#### style.css

```css
body {
  margin: 0;
  padding: 0;
}

#map {
  height: 100vh;
  width: 100vw;
}
```

### Basic JavaScript setup

```html
<html>

<head>
  <script src="https://unpkg.com/deck.gl@9.2.5/dist.min.js"></script>
  <script src="https://cdn.maptiler.com/maptiler-sdk-js/v4.2.0/maptiler-sdk.umd.min.js"></script>
  <link href="https://cdn.maptiler.com/maptiler-sdk-js/v4.2.0/maptiler-sdk.css" rel="stylesheet" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.4.2/chroma.min.js"
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    #map {
      height: 100vh;
      width: 100vw;
    }
  </style>
</head>

<body>
  <div id="map"></div>
</body>

<script type="text/javascript">
  maptilersdk.config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';

  const getPoiColor = (poi_class) => {
    const pois_class = {
      poi_shopping: chroma("#66C5CC").rgb(),
      poi_culture: chroma("#F6CF71").rgb(),
      poi_food: chroma("#F89C74").rgb(),
      poi_education: chroma("#DCB0F2").rgb(),
      poi_healthcare: chroma("#87C55F").rgb(),
      poi_public: chroma("#9EB9F3").rgb(),
      poi_sport: chroma("#FE88B1").rgb(),
      poi_station: chroma("#C9DB74").rgb(),
      poi_tourism: chroma("#8BE0A4").rgb(),
      poi_transport: chroma("#B497E7").rgb(),
      poi_accommodation: chroma("#D3B484").rgb()
    }
    return pois_class[poi_class] ? pois_class[poi_class] : chroma("#B3B3B3").rgb();
  }

  const map = new maptilersdk.Map({
    container: 'map', // container id
    style: maptilersdk.MapStyle.BASE, // style URL
    center: [-73.9843, 40.7536], // starting position [lng, lat]
    zoom: 15.5, // starting zoom
    pitch: 0
  });

  // Create a popup, but don't add it to the map yet.
  const popup = new maptilersdk.Popup({
    closeButton: false,
    closeOnClick: false,
    className: 'tooltip'
  });

  map.on('load', () => {
    const deckOverlay = new deck.MapboxOverlay({
      interleaved: false,
      layers: [
        new deck.MVTLayer({
          data: `https://api.maptiler.com/tiles/v4/{z}/{x}/{y}.pbf?key=${maptilersdk.config.apiKey}`,
          loadOptions: {
            mvt: {
              layers: ['poi_shopping', 'poi_accommodation', 'poi_culture', 'poi_food',
                'poi_education', 'poi_healthcare', 'poi_public', 'poi_sport', 'poi_station',
                'poi_tourism', 'poi_transport']
            }
          },
          minZoom: 0,
          maxZoom: 15,
          radiusMinPixels: 6,
          radiusMaxPixels: 10,
          getPointRadius: 6,
          getLineColor: [255, 255, 255],
          getFillColor: f => {
            return getPoiColor(f.properties.layerName)
          },
          getLineWidth: 1,
          lineWidthMinPixels: 1,
          pickable: true,
          onHover: info => {
            if (info.picked) {
              popup.setLngLat(info.coordinate).setHTML(`<h4>${info.object.properties.name || ""}</h4><div>${info.object.properties.class}</div>`).addTo(map);
            } else {
              popup.remove();
            }
          }
        })
      ]
    });

    map.addControl(deckOverlay);
  });    
</script>

</html>
```

Replace `YOUR_MAPTILER_API_KEY_HERE` with [your own API key](https://cloud.maptiler.com/account/keys/). Make sure to [secure the key](https://docs.maptiler.com/guides/developer/credentials/api-key/#secure-key) before you publish it.

## Related examples

### [GeoJSON in Deck.gl](https://docs.maptiler.com/deck-gl/examples/geojson/)

Examples

Visualize GeoJSON layers and arc connections in Deck.gl.

### [Interleaved Deck.gl layer](https://docs.maptiler.com/deck-gl/examples/interleaved/)

Examples

Interleave Deck.gl layers with MapTiler SDK JS maps.

### [Buildings Deck.gl MVT layer](https://docs.maptiler.com/deck-gl/examples/mvt-extrude/)

Examples

Render extruded building layers in Deck.gl using Vector Tiles.

### [3D Terrain](https://docs.maptiler.com/deck-gl/examples/3d-terrain/)

Examples

Display realistic 3D terrain in Deck.gl using MapTiler.
