在 WebGIS 里,热力图很常见:人流密度、事件热点、设施覆盖、巡查频次......它把「一堆带权重的点」渲染成连续色带,一眼看出哪里「热」、哪里「冷」。
本文将按完整链路说明:
-
理解热力图:点 + 权重 + 模糊叠加
-
用 OpenLayers 原生
Heatmap图层跑通最小示例 -
介绍
ym-giswidget-2d已封装好的Heatmap组件 -
数据格式、控制面板参数、多数据源切换与定位
先看效果:地图上叠加可调半径、模糊度、色带的热力面。

*热力图效果*
一、思路先讲清楚
热力图不是画一堆圆点,而是:
-
每个热点是一个
Point,带上weight(权重) -
图层按半径、模糊度把点「摊开」成高斯状强度场
-
强度再映射到颜色渐变(低密度 → 高密度)
可以简单记成:
坐标点 + 权重 → HeatmapLayer → 色带渲染
业务侧通常只关心两件事:
-
数据怎么组织(
x/y/weight) -
半径、模糊、透明度、色带怎么调
下面先用原生 OL 打通,再看组件封装。
二、引入 OpenLayers,准备地图与热力层
先安装依赖(Vue3 + Vite 示例):
bash
// 终端执行:npm i ol
页面里放一个地图容器(例如 id 为 map 的 div),高度自行设置。然后创建底图 + 热力图层:
bash
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import OSM from 'ol/source/OSM'
import { Heatmap as HeatmapLayer } from 'ol/layer'
import { Vector as VectorSource } from 'ol/source'
import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import { fromLonLat } from 'ol/proj'
const heatSource = new VectorSource()
// 示例点:经纬度 + 权重
[
{ lon: 117.21, lat: 31.81, weight: 20 },
{ lon: 117.22, lat: 31.815, weight: 45 },
{ lon: 117.23, lat: 31.82, weight: 70 },
{ lon: 117.24, lat: 31.825, weight: 35 },
{ lon: 117.25, lat: 31.83, weight: 90 },
].forEach((pt) => {
heatSource.addFeature(
new Feature({
geometry: new Point(fromLonLat([pt.lon, pt.lat])),
weight: pt.weight,
}),
)
})
const heatLayer = new HeatmapLayer({
source: heatSource,
blur: 15,
radius: 15,
opacity: 0.7,
gradient: ['#000000', '#800000', '#FF0000', '#FF8000', '#FFFF00'],
weight: (feature) => {
// OL 默认读 feature 上的 weight,也可自定义归一化
const w = feature.get('weight') || 0
return Math.min(1, w / 100)
},
})
const map = new Map({
target: 'map',
layers: [
new TileLayer({ source: new OSM() }),
heatLayer,
],
view: new View({
center: fromLonLat([117.23, 31.82]),
zoom: 12,
}),
})
常用可调参数:
-
radius:点半径,越大「摊」得越开 -
blur:模糊度,越大边界越柔和 -
opacity:图层不透明度 -
gradient:色带数组,从低到高

*OL 原生热力图效果*
到这里,原生链路已经跑通。工程里若还要面板拖动、多组数据切换、自动定位到点集范围,自己拼成本不低------组件库已封装好。
三、ym-giswidget-2d:Heatmap 组件已封装
译码二维组件库 ym-giswidget-2d 基于 OpenLayers Heatmap 图层,封装了:
-
可拖动的「热力图控制」面板
-
点半径 / 模糊度 / 色带 / 不透明度实时调节
-
支持多组
data切换数据源 -
渲染后自动定位到当前点集范围
1. 安装
bash
// 终端执行:npm i ym-giswidget-2d
// 或 pnpm / yarn 同理;monorepo 内可用 workspace 依赖
2. 引入样式(必做)
组件库样式不会自动注入 ,需在入口文件(如 main.js / main.ts)中显式引入:
bash
import { createApp } from 'vue'
import App from './App.vue'
import 'ym-giswidget-2d/css/index.css' // 组件库样式,必引
createApp(App).mount('#app')
若项目已用 Element Plus,可与其样式一并放在入口:
bash
import 'element-plus/dist/index.css'
import 'ym-giswidget-2d/css/index.css'
3. 最小用法
地图用 MapView,热力用 Heatmap,data 传入点集即可:
bash
import { reactive } from 'vue'
import { MapView, Heatmap } from 'ym-giswidget-2d'
const reactiveValue = reactive({ map: null })
const heatData = [
{
title: '示例热力',
points: [
{ x: 117.21, y: 31.81, weight: 20 },
{ x: 117.22, y: 31.815, weight: 45 },
{ x: 117.23, y: 31.82, weight: 70 },
{ x: 117.24, y: 31.825, weight: 35 },
{ x: 117.25, y: 31.83, weight: 90 },
],
},
]
function onInitMap(mapView) {
reactiveValue.map = mapView
// 按需叠加底图......
}
// 模板示意:
// <div class="map-heatmap-shell" style="position:relative;height:30rem;">
// <MapView @init="onInitMap" :center="[117.22718, 31.820386]" />
// <Heatmap v-if="reactiveValue.map" :map="reactiveValue.map" :data="heatData" />
// </div>
要点:
-
入口已引入
ym-giswidget-2d/css/index.css -
Heatmap与MapView建议放在同一个position: relative容器内 -
打开后会出现可拖动的控制面板;点「确认」仅收起面板,点「关闭」会移除热力图层

*组件控制面板*
四、数据格式说明
data 是数组,每一项是一组热力数据源:
bash
const heatData = [
{
title: '示例热力', // 数据源名称(多组时出现在下拉框)
points: [
{ x: 117.21, y: 31.81, weight: 20 },
{ x: 117.22, y: 31.815, weight: 45 },
],
},
]
字段说明:
-
title:数据源标题 -
points:热点数组 -
points[].x/points[].y:与地图投影一致的坐标(示例为经纬度) -
points[].weight:权重,数值越大该处越「热」
切换 data 中某一组时,组件会清空旧点、写入新点,并自动 locationGeometry 定位到当前点集范围。
五、控制面板能调什么
面板内置参数(打开即可拖动滑条 / 下拉):
-
点半径:
1 ~ 50,默认15 -
模糊度:
1 ~ 50,默认15 -
不透明度:
0 ~ 1,默认0.7 -
颜色渐变:内置多套色带
内置色带名称:
-
喷流色带
-
热力图色带(默认)
-
冷色调色带
-
大地色系
-
紫翠玉色带
面板下方有「热力分布说明」色条预览:低密度 → 中密度 → 高密度。

*色带切换效果*
六、多数据源切换
当 data.length > 1 时,面板会出现「数据源」下拉框,可在多组点集之间切换:
bash
const heatData = [
{
title: '区域甲',
points: [
{ x: 117.20, y: 31.805, weight: 30 },
{ x: 117.21, y: 31.808, weight: 55 },
{ x: 117.215, y: 31.812, weight: 75 },
],
},
{
title: '区域乙',
points: [
{ x: 117.235, y: 31.825, weight: 25 },
{ x: 117.245, y: 31.828, weight: 60 },
{ x: 117.255, y: 31.832, weight: 95 },
],
},
]
// 模板示意:
// <Heatmap v-if="map" :map="map" :data="heatData" />
切换后会自动定位到对应区域的点范围,适合「分片区 / 分时段」对比场景。

*多数据源切换*
七、和工具条一起用(可选)
若项目已使用 HorizontallyTopToolbar,也可把热力图挂成工具项,由工具条按需加载:
bash
const heatmapTool = {
id: 'heatmapTool',
title: '热力图',
classPath: '../heatmap/index.ts', // 以你项目工具条的加载约定为准
icon: './img/tool/clear.png',
isOnce: false,
isRepels: false,
data: heatData,
}
点击工具 → 打开面板与热力层;关闭面板时可移除图层,不影响其它工具。
八、小结
-
热力图本质:带权重的点 → 模糊叠加 → 色带映射
-
原生 OL:
HeatmapLayer+VectorSource+Feature(Point, weight) -
组件用法:入口引入
css/index.css,再写<Heatmap :map="map" :data="heatData" /> -
面板可调半径 / 模糊 / 透明度 / 色带;多组
data可切换并自动定位
自己实现适合理解原理、深度定制;日常业务更推荐组件封装------图层、面板、定位、多数据源都已打通。
获取 Demo 源码
关注译码设计 公众号,回复 gis2d-demo 获取ym-giswidget-2d组件使用 Demo 源码。
欢迎留言交流。
❝
技术栈参考:OpenLayers 9.x · Vue 3组件:
Heatmap(可拖动控制面板 + 多数据源热力渲染)