mapboxgl 中热力图的实现以及给热力图点增加鼠标移上 popup 效果

2023-12-28 10:49:25

概要

本篇文章还是关于最近做到的 mapboxgl 地图展开的。
借鉴官方示例:https://iclient.supermap.io/examples/mapboxgl/editor.html#heatMapLayer

效果预览

请添加图片描述

技术思路

  1. 将接口数据渲染到地图中形成热力图。
  2. 还需要将热力图中渲染的点做鼠标移上显示详情 popup 的效果。

注意:因为热力图本身不可以添加鼠标以上效果,所以还是使用了点,将鼠标以上效果加给点,然后把点的透明度设置为0,大小和热力图中点相同,即可完成上图中效果。

技术细节

  1. 地图的加载不再赘述,之前文章中写到了。
  2. 所需要规范的点数据
    其中point是自定义的,传啥都可以, createPopupStyle 就是生成 popup 的 html
featuresList.push({
   'type': 'Feature',
   'properties': {
     ...point,
     'description': that.createPopupStyle(point)
   },
   'geometry': {
     'type': 'Point',
     'coordinates': [Number(point.lng), Number(point.lat)]
   }
 })
  1. 新建热力图
/**
 * 添加热力图
 */
createHeatPoints(featuresList) {
  const that = this
  const map = this.map      
  let heatMapLayer = new mapboxgl.supermap.HeatMapLayer(
    "heatMap",
    {
      "map": map,
      "id": "heatmap",
      "radius": 50,
      // 设置图层透明度:(参数方式)
      "opacity": 0.6,
      // featureWeight指定以哪个属性值为热力权重值创建热力图:
      "featureWeight": "value",
    }
  );

  let heatPoints = {
    "type": "FeatureCollection",
    "features": featuresList
  };

  heatMapLayer.addFeatures(heatPoints);
  //        设置图层透明度:(函数方式)
  //        heatMapLayer.setOpacity(0.5);
  map.addLayer(heatMapLayer);      
},
  1. 添加透明度为0的点以及鼠标移上效果
/**
 * 添加坐标点及鼠标移上效果
 */
addPoints(featuresList) {      
  const map = this.map

  map.addSource('places', {
    'type': 'geojson',
    'data': {
      'type': 'FeatureCollection',
      'features': featuresList
    }
  })

  // 加载 circle 定位圆
  let img = {
    name: 'circle_img',
    sdf: true
  }
  this.addCircleImage(img)

  map.addLayer({
    'id': 'places',
    'type': 'symbol',
    'source': 'places',
    'layout': {
      'icon-image': img.name, // 图标ID
      'icon-size': 0.4, // 图标的大小
      // 'icon-size': ['get', 'imgSize'], // 图标的大小
      'icon-anchor': 'center', // 图标的位置
      // 'text-field': ['get', 'num'],
    },
    'paint': {
      'text-color': '#333',
      'icon-color': 'rgba(0,0,0,0)'
    },
  });

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

  map.on('mouseenter', 'places', (e) => {
    // Change the cursor style as a UI indicator.
    map.getCanvas().style.cursor = 'pointer';

    // Copy coordinates array.
    const coordinates = e.features[0].geometry.coordinates.slice();
    const description = e.features[0].properties.description;

    // 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', 'places', () => {
    map.getCanvas().style.cursor = '';
    popup.remove();
  });
},
  1. 引入图片使用方法
    注意:vue中引入图片要使用require引入,路径不能以传参的形式传入,最好写相对路径。不然都会报错。
/**
* 引入图片
 * img obj : name, sdf
 */
addCircleImage(img) {
  const map = this.map
  map.loadImage(require('./circle.png'), (error, image) => {
    if (error) throw error;
    if (!map.hasImage(img.name)) map.addImage(img.name, image, {
      sdf: img.sdf || false
    });
  })
}

小结

本方法主要还是使用点和热力图重叠同时显示效果。

文章来源:https://blog.csdn.net/lb1135909273/article/details/135236153
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。