0

I am working from this example on the Mapbox documentation page and I have managed to get points labeled onHover, but have not been able to get the actual heat map layer itself to display information on the popup. Ultimately I would like to end up with different heatmap layers that I can toggle on and off that will display information when hovered/clicked. Here is the code I have so far:

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8' />
  <title>Create a heatmap layer</title>
  <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
  <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.6.0/mapbox-gl.js'></script>
  <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.6.0/mapbox-gl.css' rel='stylesheet' />
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    #map {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }
  </style>
</head>

<body>
  <style>
    #menu {
      background: #fff;
      position: absolute;
      z-index: 1;
      top: 10px;
      right: 10px;
      border-radius: 3px;
      width: 120px;
      border: 1px solid rgba(0, 0, 0, 0.4);
      font-family: 'Open Sans', sans-serif;
    }

    #menu a {
      font-size: 13px;
      color: #404040;
      display: block;
      margin: 0;
      padding: 0;
      padding: 10px;
      text-decoration: none;
      border-bottom: 1px solid rgba(0, 0, 0, 0.25);
      text-align: center;
    }

    #menu a:last-child {
      border: none;
    }

    #menu a:hover {
      background-color: #f8f8f8;
      color: #404040;
    }

    #menu a.active {
      background-color: #3887be;
      color: #ffffff;
    }

    #menu a.active:hover {
      background: #3074a4;
    }
  </style>

  <nav id="menu"></nav>
  <div id='map'></div>

  <script>
    mapboxgl.accessToken =
      'pk.eyJ1IjoidXBjaGVlenkiLCJhIjoiY2p2Ym04aDc0MHJwejQ0bzBjcGNidjA3eiJ9.UkAX6oKYBEzgzsigkN0pbQ';
    var map = new mapboxgl.Map({
      container: 'map',
      style: 'mapbox://styles/mapbox/dark-v10',
      center: [-80.86666667, 33.83333333],
      zoom: 8.25
    });

    map.on('load', function() {
      // Add a geojson point source.
      // Heatmap layers also work with a vector tile source.
      map.addSource('earthquakes', {
        "type": "geojson",
        "data": "https://docs.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"
      });

      map.addLayer({
        "id": "earthquakes-heat",
        "type": "heatmap",
        "source": "earthquakes",
        "maxzoom": 20,
      }, 'waterway-label');

      var popup = new mapboxgl.Popup({
        closeButton: false,
        closeOnClick: false
      });

      map.on('mouseenter', 'earthquakes-heat', function(e) {
        // Change the cursor style as a UI indicator.
        map.getCanvas().style.cursor = 'pointer';

        console.log(e)

        var coordinates = e.features[0].geometry.coordinates.slice();
        var description = e.features[0].properties.number;

        // Ensure that if the map is zoomed out such that multiple
        // copies of the feature are visible, the popup appears
        // over the copy being pointed to.
        while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
          coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
        }

        // Populate the popup and set its coordinates
        // based on the feature found.
        popup.setLngLat(coordinates)
          .setHTML(description)
          .addTo(map);
      });

      map.on('mouseleave', 'earthquakes-heat', function() {
        map.getCanvas().style.cursor = '';
        popup.remove();
      });
    });

    var toggleableLayerIds = ['earthquakes-point', 'earthquakes-heat'];

    for (var i = 0; i < toggleableLayerIds.length; i++) {
      var id = toggleableLayerIds[i];

      var link = document.createElement('a');
      link.href = '#';
      link.className = 'active';
      link.textContent = id;

      link.onclick = function(e) {
        var clickedLayer = this.textContent;
        e.preventDefault();
        e.stopPropagation();

        var visibility = map.getLayoutProperty(clickedLayer, 'visibility');

        if (visibility === 'visible') {
          map.setLayoutProperty(clickedLayer, 'visibility', 'none');
          this.className = '';
        } else {
          this.className = 'active';
          map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
        }
      };

      var layers = document.getElementById('menu');
      layers.appendChild(link);
    }
  </script>
</body>
</html>

The popups work as expected when this is added and referenced in the map.on('mouseenter'...:

map.addLayer({
  "id": "earthquakes-point",
  "type": "circle",
  "source": "earthquakes",
  "minzoom": 7,
  "paint": {
    // Size circle radius by earthquake magnitude and zoom level
    "circle-radius": [
      "interpolate",
      ["linear"],
      ["zoom"],
      7, [
        "interpolate",
        ["linear"],
        ["get", "mag"],
        1, 1,
        6, 4
      ],
      16, [
        "interpolate",
        ["linear"],
        ["get", "mag"],
        1, 5,
        6, 50
      ]
    ],
    // Color circle by earthquake magnitude
    "circle-color": [
      "interpolate",
      ["linear"],
      ["get", "mag"],
      1, "rgba(33,102,172,0)",
      2, "rgb(103,169,207)",
      3, "rgb(209,229,240)",
      4, "rgb(253,219,199)",
      5, "rgb(239,138,98)",
      6, "rgb(178,24,43)"
    ],
    "circle-stroke-color": "white",
    "circle-stroke-width": 1,
    // Transition from heatmap to circle layer by zoom level
    "circle-opacity": [
      "interpolate",
      ["linear"],
      ["zoom"],
      7, 0,
      8, 1
    ]
  }
}, 'waterway-label');
  • 1
    I'm confused what you exactly want and what exactly is not possible. – Chase Choi Dec 11 '19 at 6:09
  • There's two layers: heatmap & circle. The map.on('mouseenter'... Doesn't work for the heatmap type "earthquakes-heat". Does that help clarify? – Matt Dec 11 '19 at 13:33
  • What is the target you want to add mouseenter? map or earthquakes-heat layer? Then, what action do you want to do when the event is fired? – Chase Choi Dec 11 '19 at 14:05
  • eathquakes-heat target with a pop-up onHover. If I replace eathquakes-heat with eathquakes-point it works as expected. – Matt Dec 12 '19 at 13:07
  • Hover earthquakes-point on popup then displays data as point, hover earthquakes-heat on popup then displays data as heatmap. is this what you want? – Chase Choi Dec 12 '19 at 14:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.