【2025最新】ArcGIS for JavaScript 快速实现热力图渲染

ArcGIS for JavaScript 快速实现热力图渲染 🗺️

在 GIS 开发中,热力图是展示数据密度分布的常用方式,尤其适合地震、人口、交通、商品房流量等场景。本文适用于 ArcGIS Maps SDK for JavaScri pt 4.28~4.33 版本,手把手教你使用 CSVLayer、Legend、heatmap组件,实现一个可视化效果超赞的商品房热力图,小白也能轻松上手!🚀

文章目录

  • [ArcGIS for JavaScript 快速实现热力图渲染 🗺️](#ArcGIS for JavaScript 快速实现热力图渲染 🗺️)
    • [一、效果预览 & 核心功能](#一、效果预览 & 核心功能)
    • [二、代码分步解析 🔍](#二、代码分步解析 🔍)
      • [1. 基础 HTML 结构 & 样式](#1. 基础 HTML 结构 & 样式)
      • [2. 核心 JS 逻辑(模块化写法)](#2. 核心 JS 逻辑(模块化写法))
        • (1)导入必备模块
        • [(2)配置数据来源 & 弹窗模板](#(2)配置数据来源 & 弹窗模板)
        • [(3)关键配置:热力图渲染器 🎨](#(3)关键配置:热力图渲染器 🎨)
        • [(4)创建 CSV 图层 & 标注配置](#(4)创建 CSV 图层 & 标注配置)
        • [(5)组装地图 & 视图 & 图例](#(5)组装地图 & 视图 & 图例)
    • [三、注意事项 ⚠️](#三、注意事项 ⚠️)
    • 四、所有代码
工具 /插件/系统 名 版本 说明
ArcGIS JS API 4.28~4.33 地图核心能力(底图加载、视图渲染)
天地图服务 - 提供街道、卫星、地形等底图数据源

一、效果预览 & 核心功能

先看最终实现的核心功能:

效果图1 效果图2
  1. 加载天地图底图(通过自定义tiandituLoader.js工具)

  2. 读取本地商品房.csv数据,用热力图展示销售量分布

  3. 点击热力图区域,弹窗显示对应地区及销售量详情

  4. 自动标注高销量区域(文档中预留mag>5过滤逻辑,可自定义调整)

  5. 左下角添加图例控件,直观区分热力密度等级

二、代码分步解析 🔍

1. 基础 HTML 结构 & 样式

首先搭建页面骨架,引入 ArcGIS 依赖资源,设置地图容器占满屏幕:

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>

  <!-- 引入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 个核心模块,以及天地图加载工具:

html 复制代码
<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 数据:

js 复制代码
// 商品房CSV数据路径(本地文件,需与HTML同级或调整路径)

const url = "/商品房.csv";

// 弹窗模板(用户点击热力图时弹出的信息卡片)

const template = {

  title: "{地区}",  // 弹窗标题:显示对应地区

  content: "销售量 {销售量(套)} 套",  // 弹窗内容:显示具体销售量

};
(3)关键配置:热力图渲染器 🎨

热力图的视觉效果全靠renderer控制,核心是colorStops(渐变色阶)和maxDensity(最大密度):

js 复制代码
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逻辑,需根据实际字段调整):

js 复制代码
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)组装地图 & 视图 & 图例

最后将地图、图层、视图整合,设置初始显示位置,并添加图例控件:

js 复制代码
// 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"               // 图例位置:页面左下角

);

三、注意事项 ⚠️

  1. 天地图加载问题tiandituLoader.js需要自己实现(需申请天地图 key,也可以直接在《天地图底图加载》)中直接复制,如果没有 key,可先用 ArcGIS 自带底图(如basemap: "streets")临时测试。

  2. maxDensity 调整 :如果热力图太 "散",可减小maxDensity(如 0.005);如果太 "集中",可增大(如 0.02),需根据数据量灵活调整。

  3. 跨域问题:如果本地打开 HTML 出现跨域报错,可部署到服务器(如 Nginx),或用 VSCode 的 "Live Server" 插件运行。

  4. 性能优化 :如果数据量过大(如超过 1 万条),可在 CSVLayer 中添加definitionExpression过滤数据,减少渲染压力。

四、所有代码

index.html

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

相关推荐
一位搞嵌入式的 genius11 小时前
前端实战开发(四):从迭代器到异步编程:ES6 Generator 全面解析 + 实战问题排查
开发语言·前端·es6·前端实战
来来走走11 小时前
Android开发(Kotlin) 高阶函数、内联函数
android·开发语言·kotlin
拉不动的猪11 小时前
# 关于初学者对于JS异步编程十大误区
前端·javascript·面试
Murphy_lx11 小时前
C++ thread类
开发语言·c++
彩妙不是菜喵11 小时前
C++ 中 nullptr 的使用与实践:从陷阱到最佳实践
开发语言·jvm·c++
lskisme12 小时前
springboot maven导入本地jar包
开发语言·python·pycharm
开心-开心急了12 小时前
pyside6实现win10自动切换主题
开发语言·python·pyqt·pyside
沐知全栈开发12 小时前
Foundation 模态框
开发语言
wjs202412 小时前
CSS 导航栏
开发语言
共享家952713 小时前
Qt窗口教程(上)
开发语言·qt