气象、环境类业务里常见一种数据:规则经纬度网格(每个格点一个数值)。要在地图上画成色斑图,还要可选网格线、格点数值、鼠标取值------用 OpenLayers 自己从零写 WebGL 图层成本不低。
我开源了一个小库 grid-webgl-openlayers,思路很简单:不替你创建 Map,只往现有 ol/Map 上叠加图层
示例效果图

js
ol/Map<br/>底图 + View + 控件
└── grid-webgl-openlayers 叠加
├── ChoroplethLayer WebGL 色斑图
└── GridValueLayer Canvas2D 格点数值
底图、投影、控件仍由业务方管理;库只负责 addLayer。
数据格式
JSON 描述一块矩形网格即可
json
{
"startLat": 26,
"endLat": 34.45,
"startLon": 97.25,
"endLon": 108.65,
"latStep": 0.05,
"lonStep": 0.05,
"latCount": 170,
"lonCount": 229,
"ds": [[8.37, 9, 9.72], [7.12, 8.01]]
}
ds[row][col]:从南往北、从西往东-9999表示无数据,不参与渲染和拾取
最小示例
js
npm install grid-webgl-openlayers ol
js
import Map from "ol/Map"
import View from "ol/View"
import TileLayer from "ol/layer/Tile"
import OSM from "ol/source/OSM"
import { GridMapView } from "grid-webgl-openlayers"
import "ol/ol.css"
const map = new Map({
target: "map",
view: new View({ projection: "EPSG:4326", center: [105, 30], zoom: 6 }),
layers: [new TileLayer({ source: new OSM() })],
})
const overlay = await GridMapView.create({
map,
dataUrl: "/data/arrayData.json",
showChoropleth: true, // 色斑图
showGrid: false, // 网格线
showLabels: true, // 格点数值
})
// 鼠标悬停取值
overlay.onPointerMove(({ value, lon, lat }) => {
if (value != null) console.log(value, lon, lat)
})
几行代码就能在 OSM 底图上叠色斑图。
自定义图例(模式分为色带色块)
支持不规则数值-颜色映射:
js
const colorRamp = [
[-9999, [0, 0, 0, 0]], // 无数据透明
[0, [232, 245, 233, 255]],
[7.5, [129, 199, 132, 255]],
[47.6, [27, 94, 32, 255]],
[9999, [0, 0, 0, 0]],
]
await GridMapView.create({ map, dataUrl, colorRamp })
实现要点
- WebGL 色斑:
ImageCanvas自定义图层 + Fragment Shader 按经纬度采样格点值,再查 1D 色带纹理上色。 - LOD 降采样:缩放级别低时合并格点,避免百万格点拖慢帧率。
- 格点标注:Canvas2D 按像素间距稀疏绘制,避免文字堆叠。
- 图例面板:双滑块过滤显示数值区间,
setDisplayRange(min, max)即可。
Vue 3 也有组件:GredGridMap、GredLegendPanel。
在线预览
小结
若你已有 OpenLayers 地图,只需加载规则网格 JSON,用 GridMapView.create() 叠加 WebGL 色斑图和格点标注,比从零写 Shader 省事很多。欢迎 Star 和 Issue。