【2025最新】ArcGIS for JavaScript 快速实现热力图渲染
ArcGIS for JavaScript 快速实现热力图渲染 🗺️
在 GIS 开发中,热力图是展示数据密度分布的常用方式,尤其适合地震、人口、交通、商品房流量等场景。本文适用于 ArcGIS Maps SDK for JavaScri pt 4.28~4.33 版本,手把手教你使用 CSVLayer、Legend、heatmap组件,实现一个可视化效果超赞的商品房热力图,小白也能轻松上手!🚀
文章目录
- ArcGIS for JavaScript 快速实现热力图渲染 🗺️
- 一、效果预览 & 核心功能
- 二、代码分步解析 🔍
- 1. 基础 HTML 结构 & 样式
- 2. 核心 JS 逻辑(模块化写法)
- (1)导入必备模块
- (2)配置数据来源 & 弹窗模板
- (3)关键配置:热力图渲染器 🎨
- (4)创建 CSV 图层 & 标注配置
- (5)组装地图 & 视图 & 图例
- 三、注意事项 ⚠️
- 四、所有代码
- index.html
- csv模拟数据
工具 /插件/系统 名 | 版本 | 说明 |
---|---|---|
ArcGIS JS API | 4.28~4.33 | 地图核心能力(底图加载、视图渲染) |
天地图服务 | - | 提供街道、卫星、地形等底图数据源 |
一、效果预览 & 核心功能
先看最终实现的核心功能:
效果图1 | 效果图2 |
---|---|
![]() | ![]() |
-
加载天地图底图(通过自定义
tiandituLoader.js
工具) -
读取本地
商品房.csv
数据,用热力图展示销售量分布 -
点击热力图区域,弹窗显示对应地区及销售量详情
-
自动标注高销量区域(文档中预留
mag>5
过滤逻辑,可自定义调整) -
左下角添加图例控件,直观区分热力密度等级
二、代码分步解析 🔍
1. 基础 HTML 结构 & 样式
首先搭建页面骨架,引入 ArcGIS 依赖资源,设置地图容器占满屏幕:
<!DOCTYPE html><html lang="zh"><head><meta charset="utf-8" /><!-- 移动端适配:禁止缩放,保持初始比例 --><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /><title>商品房销售量热力图</title><!-- 引入ArcGIS官方样式(控制地图控件、弹窗等UI) --><link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" /><style>/* 关键:让地图容器铺满整个页面 */html, body, #viewDiv {padding: 0;margin: 0;height: 100%;width: 100%;}</style><!-- 引入ArcGIS核心JS库(4.33版本,稳定兼容) --><script src="https://js.arcgis.com/4.33/"></script></head><body><!-- 地图渲染的核心容器,ID需与后续JS绑定 --><div id="viewDiv"></div></body></html>
2. 核心 JS 逻辑(模块化写法)
ArcGIS 4.x 推荐用module
和$arcgis.import
加载模块,避免全局变量冲突,代码结构更清晰,分 5 步实现:
(1)导入必备模块
先加载地图、CSV 数据层、视图、图例 4 个核心模块,以及天地图加载工具:
<script type="module">// 1. 导入ArcGIS官方核心模块(按需加载,减少体积)const [Map, CSVLayer, MapView, Legend] = await $arcgis.import(["@arcgis/core/Map.js", // 地图实例(管理底图和图层)"@arcgis/core/layers/CSVLayer.js", // CSV数据图层(加载商品房数据)"@arcgis/core/views/MapView.js", // 2D视图(渲染地图到页面)"@arcgis/core/widgets/Legend.js" // 图例控件(展示热力等级)]);// 2. 导入自定义天地图加载工具(需本地准备tiandituLoader.js,下文有说明)import { loadTiandituBasemap } from './js/tiandituLoader.js';const { tiandituBasemap } = await loadTiandituBasemap();</script>
(2)配置数据来源 & 弹窗模板
-
数据来源:本地
商品房.csv
(需确保路径正确,字段包含 “地区”“销售量(套)”) -
弹窗模板:点击热力图时显示详情,用
{字段名}
直接关联 CSV 数据:
// 商品房CSV数据路径(本地文件,需与HTML同级或调整路径)const url = "/商品房.csv";// 弹窗模板(用户点击热力图时弹出的信息卡片)const template = {title: "{地区}", // 弹窗标题:显示对应地区content: "销售量 {销售量(套)} 套", // 弹窗内容:显示具体销售量};
(3)关键配置:热力图渲染器 🎨
热力图的视觉效果全靠renderer
控制,核心是colorStops
(渐变色阶)和maxDensity
(最大密度):
const renderer = {type: "heatmap", // 明确图层类型为热力图colorStops: [ // 渐变色阶:从透明黄色到红棕色,共13个等级{ color: "rgba(255, 255, 0, 0)", ratio: 0 }, // 0%:透明(无数据区域){ color: "#ffff00", ratio: 0.083 }, // 8.3%:亮黄色(低销量){ color: "#ffd700", ratio: 0.166 }, // 16.6%:金黄色{ color: "#ffc107", ratio: 0.249 }, // 24.9%:琥珀色{ color: "#ff9800", ratio: 0.332 }, // 33.2%:橙色{ color: "#ff7043", ratio: 0.415 }, // 41.5%:深橙色{ color: "#ff5722", ratio: 0.498 }, // 49.8%:橙红色{ color: "#ff4500", ratio: 0.581 }, // 58.1%:橙红色(加深){ color: "#ff3a00", ratio: 0.664 }, // 66.4%:浅红色{ color: "#ff2400", ratio: 0.747 }, // 74.7%:红色(加深){ color: "#e61900", ratio: 0.83 }, // 83%:深红色{ color: "#cc1400", ratio: 0.913 }, // 91.3%:暗深红色{ color: "#b30f00", ratio: 1 } // 100%:红棕色(高销量密集区)],maxDensity: 0.01, // 最大密度(关键参数!值越小,热力越集中;值越大越分散)minDensity: 0, // 最小密度(默认0即可,代表无数据区域)};
(4)创建 CSV 图层 & 标注配置
CSVLayer 是加载本地 CSV 数据的核心,同时可配置 “高销量区域标注”(文档中预留mag>5
逻辑,需根据实际字段调整):
const layer = new CSVLayer({url: url, // 绑定商品房CSV数据路径title: "商品房销售量热力图", // 图层名称(将显示在图例上)copyright: "模拟数据", // 版权信息(可替换为实际数据来源)popupTemplate: template, // 绑定弹窗模板,点击显示详情renderer: renderer, // 绑定热力图渲染器,控制视觉效果labelsVisible: true, // 开启标注功能(显示高销量区域标识)labelingInfo: [ // 标注具体配置(需根据CSV实际字段调整){symbol: {type: "text", // 标注类型:文本color: "white", // 文字颜色:白色(醒目)font: { family: "Noto Sans", size: 8 }, // 字体:无衬线字体,8号大小haloColor: "#472b77", // 文字光晕:紫色(突出文字,避免被热力图覆盖)haloSize: 0.75, // 光晕大小:0.75像素(适中)},labelPlacement: "center-center", // 标注位置:热力图中心点labelExpressionInfo: {// 标注内容:文档中用$feature.mag,需替换为CSV的“销售量(套)”字段expression: "Text($feature.销售量(套), '#')", },// 过滤条件:文档中用mag>5,需替换为实际高销量阈值(如销售量>100)where: "销售量(套) > 100", },],});
(5)组装地图 & 视图 & 图例
最后将地图、图层、视图整合,设置初始显示位置,并添加图例控件:
// 1. 创建地图实例(绑定天地图底图 + 商品房热力图层)const map = new Map({basemap: tiandituBasemap, // 底图:天地图(需tiandituLoader.js支持)layers: [layer], // 图层:添加商品房热力图层});// 2. 创建2D视图(绑定页面容器,设置初始显示参数)const view = new MapView({container: "viewDiv", // 绑定地图容器ID(与HTML中的div#viewDiv对应)center: [116.4074, 39.9042], // 初始中心点:北京经纬度(可根据数据区域调整)zoom: 2, // 初始缩放级别:2级(全球视角,可按需调大)map: map, // 关联地图实例});// 3. 添加图例控件(放在左下角,方便查看热力等级)view.ui.add(new Legend({ view: view }), // 图例绑定当前视图"bottom-left" // 图例位置:页面左下角);
三、注意事项 ⚠️
-
天地图加载问题:
tiandituLoader.js
需要自己实现(需申请天地图 key,也可以直接在《天地图底图加载》)中直接复制,如果没有 key,可先用 ArcGIS 自带底图(如basemap: "streets"
)临时测试。 -
maxDensity 调整:如果热力图太 “散”,可减小
maxDensity
(如 0.005);如果太 “集中”,可增大(如 0.02),需根据数据量灵活调整。 -
跨域问题:如果本地打开 HTML 出现跨域报错,可部署到服务器(如 Nginx),或用 VSCode 的 “Live Server” 插件运行。
-
性能优化:如果数据量过大(如超过 1 万条),可在 CSVLayer 中添加
definitionExpression
过滤数据,减少渲染压力。
四、所有代码
index.html
<!DOCTYPE html>
<!doctype html>
<html lang="zh"><head><meta charset="utf-8" /><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /><title>热力图</title><link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" /><style>html,body,#viewDiv {padding: 0;margin: 0;height: 100%;width: 100%;}</style><script src="https://js.arcgis.com/4.33/"></script><script type="module">const [Map, CSVLayer, MapView, Legend] = await $arcgis.import(["@arcgis/core/Map.js","@arcgis/core/layers/CSVLayer.js","@arcgis/core/views/MapView.js","@arcgis/core/widgets/Legend.js",]);import { loadTiandituBasemap } from './js/tiandituLoader.js';const {tiandituBasemap } = await loadTiandituBasemap();const url = "/商品房.csv";const template = {title: "{地区}",content: "销售量 {销售量(套)}.",};//最大像素强度用于指定颜色//从colorStops属性中的连续颜色渐变const renderer = {type: "heatmap",colorStops: [{ color: "rgba(255, 255, 0, 0)", ratio: 0 }, // 透明黄色(起始){ color: "#ffff00", ratio: 0.083 }, // 亮黄色{ color: "#ffd700", ratio: 0.166 }, // 金黄色{ color: "#ffc107", ratio: 0.249 }, // 琥珀色{ color: "#ff9800", ratio: 0.332 }, // 橙色{ color: "#ff7043", ratio: 0.415 }, // 深橙色{ color: "#ff5722", ratio: 0.498 }, // 橙红色{ color: "#ff4500", ratio: 0.581 }, // 橙红色(加深){ color: "#ff3a00", ratio: 0.664 }, // 浅红色{ color: "#ff2400", ratio: 0.747 }, // 红色(加深){ color: "#e61900", ratio: 0.83 }, // 深红色{ color: "#cc1400", ratio: 0.913 }, // 暗深红色{ color: "#b30f00", ratio: 1 } // 红棕色(终点)],maxDensity: 0.01,minDensity: 0,};const layer = new CSVLayer({url: url,title: "热力显示",copyright: "模拟数据",popupTemplate: template,renderer: renderer,labelsVisible: true,labelingInfo: [{symbol: {type: "text", color: "white",font: {family: "Noto Sans",size: 8,},haloColor: "#472b77",haloSize: 0.75,},labelPlacement: "center-center",labelExpressionInfo: {expression: "Text($feature.mag, '#.0')",},where: "mag > 5",},],});const map = new Map({basemap: tiandituBasemap,layers: [layer],});const view = new MapView({container: "viewDiv",center: [116.4074,39.9042],zoom: 2,map: map,});view.ui.add(new Legend({view: view,}),"bottom-left",);</script>
</head><body><div id="viewDiv"></div>
</body></html>
csv模拟数据
id,地区,latitude,longitude,销售量(套)
1,北京,39.9042,116.4074,50000
2,上海,31.2304,121.4737,60000
3,广州,23.1291,113.2644,45000
4,深圳,22.5437,114.0579,40000
5,杭州,30.2869,120.1583,35000
6,南京,32.0406,118.7677,30000
7,成都,30.5742,104.0631,48000
8,武汉,30.5928,114.3055,33000
9,西安,34.2647,108.9542,38000
10,重庆,29.5634,106.5504,55000
#ArcGISforJS