纯HTML无法实现地图热力图,必须用Leaflet+leaflet.heat组合;数据格式为[纬度,经度,权重]三元组,中国中心坐标35.8617,104.1956,缩放级4~5,需注意经纬度顺序、坐标桥接与容器尺寸同步。

纯 HTML 做不了地图热力覆盖——它没有坐标系、不理解经纬度、也不能把数值映射成颜色梯度。所谓“HTML 实现”,本质是选对技术栈 + 绕过坐标陷阱,最稳路径是 Leaflet + leaflet.heat。
为什么不能直接用 heatmap.js 挂 document.body
很多人抄文档把 HeatmapOverlay 实例 append 到 document.body,结果热力点永远钉在左上角,拖动或缩放地图完全不跟着走。这不是 bug,是设计如此:heatmap.js 本身只认像素坐标,和地图零耦合。它根本不知道当前地图中心在哪、缩放多少、投影怎么算。
- 必须用桥接层(比如
HeatmapOverlay.onAdd)把map.latLngToLayerPoint()的转换结果喂给它 - 更简单的方式:别单独引
heatmap.js,直接用leaflet.heat插件,它已封装好所有坐标桥接逻辑 - 若坚持用原生
heatmap.js,每次地图移动后得手动调heatmap.setData(points.map(p => map.latLngToLayerPoint(p)))
L.heatLayer 数据格式必须是 [lat, lng, weight] 三元组
顺序错一个字符就全偏移——Leaflet 要 [纬度, 经度],而百度/高德是 [经度, 纬度],硬套会偏移上千公里。且数据必须是数组,不能是对象,否则 leaflet.heat 会静默失败,控制台不报错也不渲染。
- 正确写法:
[[39.915, 116.404, 5], [39.920, 116.395, 8]] - 错误写法:
[{lat: 39.915, lng: 116.404, value: 5}]或[[116.404, 39.915, 5]] - 中国地理中心建议用
[35.8617, 104.1956],不是北京坐标;缩放级别设为 4~5 才能完整显示疆域
百度地图热力图要开插件权限,且引入顺序不能错
BMapLib.HeatmapOverlay 不是默认可用功能,必须在百度地图控制台单独开通「热力图」服务,否则调用 setDataSet 会报 undefined is not a function。而且引入顺序一错就白屏。
立即学习“前端免费学习笔记(深入)”;
-
BMap必须在BMapLib之前加载 -
<script src="http://api.map.baidu.com/api?v=2.0&ak=xxx"></script>中的ak参数必须带全,漏一个字符就白屏 - 坐标必须用
BMap.Point(lng, lat)(注意:这里是经度在前),和 Leaflet 完全相反 - 热力图图层需显式调用
map.addOverlay(heatmapOverlay),只new不add就不会显示
容器尺寸、定位与移动端 touch 事件要特别处理
热力图图层依赖容器真实渲染尺寸和定位上下文。常见问题包括 canvas 模糊、悬停失效、移动端响应迟钝。
- 地图容器必须有明确宽高(不能靠内容撑开),且
position: relative - 嵌在 flex/grid 面板里时,
window.innerWidth不可靠,要用getBoundingClientRect()拿真实尺寸 - 移动端 touch 事件默认被地图拦截,要加
map.disableDragging()才能让热力图响应 hover,但代价是地图不能拖拽——得权衡 - iOS Safari 对 canvas 渲染有兼容性问题,大数据量建议加采样或聚类,避免卡顿
真正容易被忽略的是坐标桥接这个环节:不是“加了库就能跑”,而是每一步坐标转换都得对齐——地图 CRS、热力图输入格式、容器定位、移动端事件坐标系,四个点只要一个没对上,热力图就飘在天上或堆在角落。



















