腾讯地图Web版解决热力图被轮廓覆盖的问题

前言

你好,我是喵喵侠。

还记得那天傍晚,我正对着电脑调试一个腾讯地图的热力图页面。项目是一个区域人流密度可视化模块,我加了一个淡蓝色的轮廓图层用于表示区域范围,热力图放在下面用于展示人流热度。效果一预览,瞬间眉头皱了起来:热力图几乎被轮廓"盖没了"!

经过一番摸索与咨询官方技术支持,问题终于迎刃而解。这篇文章就来分享这次踩坑经历,告诉你该怎么正确"安排"这两张图层的关系。

问题复现

为了复现这个问题,我在官方demo的基础上,写了一个问题demo如下:

html 复制代码
<!--
 * @Author: Cooper cooperx@foxmail.com
 * @Date: 2025-06-11 09:24:38
 * @LastEditors: Cooper cooperx@foxmail.com
 * @LastEditTime: 2025-06-11 09:38:01
 * @FilePath: /mapjs/qqmap.html
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>腾讯地图热力图与轮廓示例</title>
  <meta name="viewport"
    content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  <style type="text/css">
    html,
    body {
      width: 100%;
      height: 100%;
    }

    * {
      margin: 0;
      padding: 0;
    }

    #container {
      height: 90vh;
      width: 100vw;
    }

    #setOptions {
      position: absolute;
      top: 10px;
      left: 10px;
      z-index: 10;
      background: rgba(255, 255, 255, 0.9);
      border-radius: 8px;
      box-shadow: 0 2px 8px #0001;
      padding: 8px;
    }

    button {
      margin: 4px;
      padding: 6px 12px;
      border: 1px solid #555;
      border-radius: 4px;
      background: #f5f5f5;
      cursor: pointer;
    }
  </style>
  <script charset="utf-8"
    src="https://map.qq.com/api/js?v=2.exp&libraries=visualization&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"></script>
</head>

<body>
  <div id="container"></div>
  <div id="setOptions">
    <button id="show">显示/隐藏热力图</button>
    <button id="data">更新数据</button>
    <button id="radius">改变半径</button>
    <button id="gradient">改变颜色</button>
    <button id="opacity">改变透明度</button>
    <button id="destroy">销毁热力图</button>
    <button id="toggleContour">显示/隐藏轮廓</button>
  </div>
  <script>
    window.onload = function () {
      // 创建地图
      var map = new qq.maps.Map(document.getElementById("container"), {
        center: new qq.maps.LatLng(39.9847, 116.3074),
        zoom: 12
      });
      // 创建热力图对象
      var heat = new qq.maps.visualization.Heat({
        map: map,
        radius: 30,
      });
      // 获取热力数据
      var data = getHeatData();
      heat.setData(data);

      // 以热力图中心点为中心,生成覆盖热力图的轮廓
      function generateCircleContour(center, radius, pointsCount) {
        var contour = [];
        for (var i = 0; i < pointsCount; i++) {
          var angle = 2 * Math.PI * i / pointsCount;
          var lat = center.lat + radius * Math.sin(angle);
          var lng = center.lng + radius * Math.cos(angle);
          contour.push(new qq.maps.LatLng(lat, lng));
        }
        // 闭合多边形
        contour.push(contour[0]);
        return contour;
      }
      var center = { lat: 39.9847, lng: 116.3074 };
      var radius = 0.08; // 与热力图点分布半径一致
      var haidianPath = generateCircleContour(center, radius, 40);
      var contour = new qq.maps.Polygon({
        map: map,
        path: haidianPath,
        strokeColor: new qq.maps.Color(173, 216, 230, 0.8),
        fillColor: new qq.maps.Color(173, 216, 230, 0.5),
      });
      var contourVisible = true;

      // 按钮事件
      document.getElementById("setOptions").addEventListener("click", function (e) {
        var target = e.target;
        switch (target.id) {
          case "show":
            if (heat.visible) {
              heat.hide();
            } else {
              heat.show();
            }
            break;
          case "data":
            data = getHeatData(200);
            heat.setData(data);
            break;
          case "radius":
            let radius = heat.getRadius();
            heat.setRadius(radius + 10 > 80 ? 20 : radius + 10);
            break;
          case "gradient":
            let gradient = heat.getGradient();
            gradient[1.0] = "#fff";
            heat.setGradient(gradient);
            break;
          case "opacity":
            let opacity = heat.getOpacity();
            opacity = [0.1, 0.8];
            heat.setOpacity(opacity);
            break;
          case "destroy":
            heat.destroy();
            break;
          case "toggleContour":
            contourVisible = !contourVisible;
            contour.setMap(contourVisible ? map : null);
            break;
          default:
        }
      });

      function getHeatData(cnt, max, min) {
        let data = [];
        let center = { lat: 39.9847, lng: 116.3074 };
        cnt = cnt || 100;
        max = max || 100;
        min = min || 0;
        for (let index = 0; index < cnt; index++) {
          let r = Math.random() * 0.08;
          let angle = Math.random() * Math.PI * 2;
          let heatValue = Math.random() * (max - min) + min;
          data.push({
            lat: center.lat + r * Math.sin(angle),
            lng: center.lng + r * Math.cos(angle),
            value: heatValue
          });
        }
        return { max: max, min: min, data: data };
      }
    }
  </script>
</body>

</html>

可以看到这样效果如下图所示,热力图被盖住。

解决办法

我咨询官方给出解决办法是,设置热力图的层级比轮廓大就可以了,也就是设置zIndex。

设置了层级后,效果如下,这样就明显多了!

总结

通过本文的介绍,相信你已经掌握了腾讯地图中热力图被遮挡的解决技巧 ------ 只需要添加 zIndex 属性,就能轻松让热力图"浮上来"。

这个问题本身不复杂,但由于文档提示不足,很容易被忽略。很多开发者第一时间想到的是换透明度、调整颜色,其实只差了一个小小的 zIndex。

这种操作看似简单,其实很多人都没用过,写这篇文章就是为了帮大家少走弯路。

如果你也觉得有帮助,记得点赞、收藏、关注支持我哟~我们下篇地图踩坑笔记再见!

相关推荐
Dovis(誓平步青云)2 分钟前
导览音频切换太快,旧讲解不能覆盖新展品
android·前端·javascript·ecmascript·音视频·宠物
福兮说11 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理11 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆66612 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
凤城老人12 小时前
从 PyQt6 到 Electron:给 Edge TTS 做一个“多角色配音机“的踩坑手记
javascript·typescript·electron
Dovis(誓平步青云)12 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan13 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_13 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒14 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技14 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端