news 2026/9/9 11:18:01

ECharts中国地图JSON文件实战指南:从获取注册到避坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ECharts中国地图JSON文件实战指南:从获取注册到避坑

简介:面向Web前端与数据可视化开发者的ECharts中国地图JSON数据包,包含全国及各省、地市级行政区划的边界坐标、地区编码及嵌套子区域信息,可直接用于地图注册、数据绑定与区域着色,解决ECharts地图开发中地理数据获取与格式匹配的常见问题。压缩包共424个json文件,整体约7.96MB,文件按行政区划代码命名,既有全国总图,也有分省、分地市文件,便于按需加载和地图下钻场景使用。已有3349人学习下载。通过该数据包,读者可省去手动整理GeoJSON的繁琐步骤,快速搭建中国地图可视化页面;配合ECharts的registerMap与setOption接口,能够实现点击高亮、悬浮提示等交互效果。资源适配数据大屏、管理后台、区域统计报告等常见项目,适合具备一定JavaScript基础、正在实践ECharts地图功能的开发者参考使用。 做前端可视化这块,凡是跟中国地图沾边的需求,几乎绕不开 ECharts。而 ECharts 画地图的前提,就是得有一份能用的中国地图 JSON 文件。这个文件说大不大,说小不小,但真到用的时候,坑是一个接一个:要么地图显示不出来,要么数据对不上号,要么拿到的 GeoJSON 坐标系有问题。这篇就把我实际折腾 ECharts 中国地图 JSON 文件的经验完整梳理一遍,从文件来源、格式结构、注册方式到常见报错,一次性讲透,给正在被地图数据折磨的各位一个能直接抄作业的参考。

1. 为什么 ECharts 画中国地图必须先有 JSON 文件

先聊一个基础问题:ECharts 本身是不带任何地图数据的,它只是一个纯粹的绘图引擎。你把 ECharts 引入项目后,它能画折线图、柱状图、饼图,因为这些图形是它自己用 Canvas 或 SVG 绘制的,不需要外部数据源。但地图不一样,地图的边界轮廓、省市分布、经纬度坐标,这些信息必须由外部的地理数据来提供,ECharts 只是负责把这个数据渲染出来。

这个外部数据就是 GeoJSON 格式的 JSON 文件。你可以把它理解成一份“地理信息清单”,里面记录了每个省、每个市、每个县的边界坐标点集合。ECharts 拿到这份清单后,才能知道“北京市”的轮廓是由哪些坐标点连成的,“广东省”又是由哪些坐标点围出来的。没有这份文件,你调用echarts.registerMap('china', ...)的时候直接就会报错,地图区域在图表里就是一个空白。

这里有个特别容易混淆的概念,很多人以为echarts官方包或者 CDN 上那个china.js文件就是地图数据本身。实际上,china.js只是一个封装好的脚本文件,它内部做的就是一件事:把一份 GeoJSON 数据通过echarts.registerMap('china', geoJson)注册到 ECharts 实例里。所以你完全可以不用china.js,自己找一份 JSON 文件,手动调用registerMap注册,效果一模一样。理解了这一层,后面遇到各种地图不显示的奇怪问题,排查方向就清晰多了。

2. 中国地图 GeoJSON 的获取途径与选型思路

既然 JSON 文件是刚需,那这个文件从哪来?我前前后后试过不下十种来源,真正稳定靠谱的就那么几个。这里按优先级排序,并说明各自适合什么场景。

2.1 DataV.GeoAtlas 阿里云数据可视化平台

这个是我现在的主力数据源,地址是 datav.aliyun.com/portal/school/atlas/geo_selector。它提供全国、各省、各市的 GeoJSON 下载,数据更新及时,坐标系是 GCJ-02 火星坐标系。

使用方式很简单:打开页面后,点击具体省份,右侧会出现一个 JSON 链接,直接右键另存为就能拿到文件。这个数据源最大的优点是细粒度到区县级别,比如你需要做某个省的地图,连省级边界带市级边界的文件都能直接下载,不需要自己用工具切割。

一个小提醒:DataV 的 JSON 文件里带有features数组,每个 feature 的properties字段里有nameadcodecenter等信息。adcode是行政区划代码,这个是做数据映射时的黄金钥匙,后面会详细说。

2.2 echarts-maps 等 npm 包

如果你用的是 npm 管理项目,可以直接安装echarts-maps这类包。装完之后在 node_modules 里能找到china.json或者china.js。但这方式有个问题:包里的数据相对陈旧,而且很多包已经停止维护了,数据中的行政区划变动(比如某些地区代码调整)不会及时跟上。

我自己的习惯是:先用 npm 包快速验证地图能不能渲染,真正上线前再换成 DataV 或自己裁剪的数据。这样做的好处是开发阶段速度快,import chinaJson from 'echarts-maps/china.json'一行就能搞定,省去手动下载文件的步骤。

2.3 从 Highcharts 等其它图表库转包

网上有些老教程会教你去别的图表库源码里提取 GeoJSON,比如从 Highcharts 的 mapdata 模块里找。这个方法在早期挺实用,因为很多图表库把地图数据公开在 GitHub 上。但现在我不太推荐,原因有两个:一是这些数据可能是 WGS84 坐标系(后面会讲坐标系的坑),二是提取过程繁琐,要处理文件格式差异。

2.4 自己用工具生成裁剪

如果你需要的是非标准的自定义区域(比如某一个县、某几个市拼起来),现成的数据源可能不够用。这时候需要借助地图编辑工具。常见做法是用 GeoJson.io 这个在线编辑器,把下载的完整中国地图拖进去,手动选中需要的区域删除其余部分,然后导出新的 GeoJSON。

用 GeoJson.io 有个细节值得注意:导出格式要选GeoJSON,不要选TopoJSON。ECharts 对 TopoJSON 的原生支持不好,你需要额外用topojson-client转换后才能用。省一步是一步,直接导出 GeoJSON 最省心。

2.5 数据来源对比总结

获取方式数据粒度更新速度操作难度推荐度
DataV.GeoAtlas省/市/区县较及时很高
npm 包省/市一般中等
其它图表库转包省/市较高不推荐
GeoJson.io 自剪自定义手动中等按需

3. GeoJSON 文件的核心结构与坐标系避坑指南

拿到一份中国地图 JSON 文件后,先别急着上代码,建议用文本编辑器打开看一眼结构。虽然 GeoJSON 的字段不多,但理解了它,后面调试地图显示问题会顺畅很多。

3.1 中国地图 GeoJSON 的标准结构

一份合法的 GeoJSON 通常长这样:

{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "北京市", "adcode": 110000, "center": [116.405285, 39.904989] }, "geometry": { "type": "MultiPolygon", "coordinates": [[[...]]] } } ] }

这里有几个字段需要理解:

  • type:最外层固定是FeatureCollection,表示这是一个要素集合。
  • features:数组,里面每一项代表一个地理区域(省、市等)。
  • properties.name:区域名称,这个通常是做数据关联的键。
  • properties.adcode:行政区划代码,唯一标识一个区域,比名称更可靠。
  • geometry:几何信息,记录了边界坐标点。Polygon表示单个闭合多边形,MultiPolygon表示由多个多边形组成(像广东省有众多岛屿,用到的就是 MultiPolygon)。

3.2 坐标系陷阱:GCJ-02 还是 WGS84

坐标系这个问题,新手基本都会踩一次坑。中国地图的地理数据主要存在两套坐标系:

  • WGS84:国际通用的 GPS 坐标系,GPS 设备直接输出的就是它。
  • GCJ-02:中国国测局加密坐标系,也叫“火星坐标系”。国内绝大多数地图服务商(高德、DataV 等)使用这套。

ECharts 本身对坐标系没有强制要求,但如果你把 GCJ-02 的地图数据和 WGS84 的坐标点混在一起用,就会出现点位偏移。比如你用 WGS84 经纬度在 GCJ-02 地图上标注某个城市的位置,标记点可能会飞到几十公里外。

实操中的建议是:地图数据用哪套坐标系,标注点数据尽量也统一。如果你的业务数据是 GPS 设备采集的 WGS84 坐标,而地图用的是 DataV 的 GCJ-02 数据,就需要对坐标做转换。网上有 GCJ-02 和 WGS84 互转的算法代码,直接搜“coordtransform”就行,或者用gcoord这个 npm 库来转换。

3.3 属性名称规范化

还有一个小细节:不同来源的 JSON 文件,properties里的字段名可能不一样。有的叫name,有的叫NAME,有的是na。ECharts 默认用name字段作为区域名称。如果你的 JSON 文件里字段名不是name,需要在注册地图前做一次字段映射,否则地图上的区域名显示不出来。

比如你拿到一份字段名是NAME的 JSON,可以这样处理:

geoJson.features.forEach(item => { item.properties.name = item.properties.NAME; });

4. 完整实操:从注册地图到数据上色

理论说完了,接下来是实战环节。我用一个完整的例子演示:如何把一份中国地图 JSON 文件加载进项目,并给不同省份按数值上色。这个例子覆盖了大部分地图场景,包括基础渲染、数据关联、分段颜色。

4.1 准备基础环境与文件

假设你用的是 Vue 3 + Vite 项目,先安装 ECharts:

npm install echarts

然后在项目src/assets/目录下放一份china.json文件(从 DataV 下载)。注意,JSON 文件放本地后,用import引入即可,Vite 和 Webpack 都支持直接导入 JSON。

4.2 加载并注册地图

import * as echarts from 'echarts'; import chinaJson from './assets/china.json'; // 注册地图,第一个参数是地图名称,后面使用时要保持一致 echarts.registerMap('china', chinaJson);

registerMap一旦调用,全局的 ECharts 实例都能使用名为china的地图。这里有个很多人不知道的细节:如果你将chinaJson对象直接传入,之后又修改了这个对象的内容,地图是不会自动刷新的,需要重新调用registerMap。所以如果你有动态更新地图数据的需求,记得在更新前再次注册。

4.3 配置 series-map 与 visualMap

注册完之后,写最基础的可视化配置。需求场景:展示各省份的某个业务指标,比如销售额,数值越高颜色越深。

const chart = echarts.init(document.getElementById('mapContainer')); chart.setOption({ tooltip: { trigger: 'item', formatter: params => `${params.name}: ${params.value || 0}` }, visualMap: { type: 'piecewise', pieces: [ { min: 10000, label: '1万以上' }, { min: 5000, max: 9999, label: '5000-9999' }, { min: 1000, max: 4999, label: '1000-4999' }, { min: 0, max: 999, label: '0-999' } ], left: 20, bottom: 20 }, series: [{ type: 'map', map: 'china', roam: true, label: { show: true, fontSize: 10 }, data: [ { name: '北京市', value: 12000 }, { name: '广东省', value: 8000 } // 其他省份数据... ] }] });

这段代码里面的关键点:

  • series.typemapmap字段填的是registerMap时自定义的字符串。
  • data数组中的name字段必须与 JSON 中properties.name一一对应,对不上就显示不出来。
  • visualMap负责图例和颜色映射。typepiecewise还是continuous取决于业务需求。分段型适合少数几个区间对比,连续型适合数值梯度较平滑的场景。

4.4 让地图自适应容器大小

地图画完后,浏览器窗口改变大小,图不会自动跟着变,需要监听 resize 事件:

window.addEventListener('resize', () => { chart.resize(); });

在 Vue 组件中,记得在onUnmounted里移除监听,并调用chart.dispose()释放实例,避免内存泄漏。

4.5 处理偏远岛屿等小区域显示问题

中国地图有个经典问题:南海诸岛默认在地图右下角以插图形式展示,但有时候你放大南海区域会发现它是一块空白。这个问题通常是数据源导致的,DataV 的全国 JSON 里,南海诸岛是包含在图内的,但 ECharts 渲染时默认的视角可能没把它显示全。

解决办法是在series里设置centerzoom来控制地图的显示范围:

series: [{ type: 'map', map: 'china', center: [104, 35], // 中心点经纬度,大约在中国几何中心 zoom: 1.2 // 缩放比例 }]

如果你只关注大陆区域,可以适当加大 zoom,但要注意别把南海诸岛的图例挤出画布。这里没有完美的参数,只能根据实际效果微调。

5. 热门场景扩展:3D 地图、城市标记与分段颜色优化

做完基础的 2D 地图,再看几个高频的进阶需求。这些需求在热词里频繁出现,也是我实际接到过不少次的需求类型。

5.1 用 echarts-gl 做 3D 中国地图

3D 地图的核心是echarts-gl扩展包。安装方式:

npm install echarts-gl

使用时的配置思路和 2D 地图完全不同。3D 地图通常用map3D系列,配合geo3Dscatter3D组合使用。这里贴一段简化版的代码:

import 'echarts-gl'; chart.setOption({ geo3D: { map: 'china', roam: true, itemStyle: { color: '#1a2b52', opacity: 1, borderWidth: 1, borderColor: '#5b9bd5' }, label: { show: false }, light: { main: { intensity: 1.2, shadow: true } }, viewControl: { distance: 100, alpha: 40, beta: 0 } }, series: [{ type: 'scatter3D', coordinateSystem: 'geo3D', data: [[116.405285, 39.904989, 100], [113.264385, 23.129112, 80]] // 每个元素是 [经度, 纬度, 数值] }] });

这里值得多说两句:geo3D只负责底层的 3D 地理空间,真正要展示业务指标,通常在scatter3D或者bar3D里做。比如你要展示某个城市的数值,就在scatter3Ddata里给出该城市的经纬度和大小,这样点会悬浮在 3D 地图的对应位置上。

3D 地图的常见问题是性能。数据量大时,3D 渲染会把浏览器卡死。我的经验是:scatter3D的数据点控制在 1000 个以内,geo3D的地图 JSON 最好做一次简化(减少边界坐标点数量),否则移动端设备基本带不动。

5.2 给指定城市标记数量

“怎么给某些市标记数量”——这是做省级地图时最常见的需求。你有一份市级数据,地图底图是省级 JSON,这时候需要拆分为两步:

第一步,拿到包含市级边界的地图 JSON。如果你下载的是某个省的地图 JSON,它的features已经是市级粒度,那直接用即可。但如果你只有全国 JSON,要展示市级数据,就需要用 GeoJson.io 把对应省的区域单独裁剪出来。

第二步,在series.data里配置每个市的数据:

series: [{ type: 'map', map: 'jiangsu', // 假设你注册了江苏省地图 data: [ { name: '南京市', value: 120 }, { name: '苏州市', value: 200 }, { name: '无锡市', value: 80 } ] }]

如果你用的底图是全国 JSON,name就对应省份名称。所以你的数据粒度决定了你用哪份 JSON,别拿省级数据配全国底图,那是对不上的。

5.3 visualMap pieces 调整分段(从 9 段变 10 段)

热词里有一条很具体:echarts visualmap piecesecharts地图9段图变10段图。这其实就是在说分段图例的配置。ECharts 的visualMap.pieces可以配置任意数量的分段,没有默认 9 段的限制。

比如原来你的图例是 9 段,想拆成 10 段,只需要在pieces数组里加一段即可:

pieces: [ { min: 10000 }, { min: 8000, max: 9999 }, { min: 6000, max: 7999 }, { min: 4000, max: 5999 }, { min: 2000, max: 3999 }, { min: 1000, max: 1999 }, { min: 500, max: 999 }, { min: 100, max: 499 }, { min: 0, max: 99 } ]

这是 9 段,想变 10 段,就在最前面或最后面再插入一段。分段原则是覆盖所有数据范围,且区间不重叠。这里有个易错点:如果数据里有负值,min要设置成负数范围,否则负值没有对应颜色。

6. 常见问题排查实录与避坑技巧汇总

最后这部分,我按真实工作中排查问题的思路,整理了高频报错和现象,以及对应的解决路径。

6.1 地图区域全部空白,控制台报错 “Map china not exists”

这个报错说明china这个地图名称没有通过registerMap注册。排查顺序:

  1. 检查echarts.registerMap('china', data)是否在setOption之前执行。
  2. 检查registerMap的第一个参数是否和series.map的值一致。
  3. 检查 JSON 数据是否为undefined,可能是文件路径写错了或者异步加载没等返回就setOption

如果 JSON 是异步获取的,务必在setOption前等待数据返回:

const response = await fetch('/map/china.json'); const chinaJson = await response.json(); echarts.registerMap('china', chinaJson); chart.setOption(option);

6.2 地图能渲染,但部分省份没有颜色

这几乎都是数据关联的问题:data数组里的name跟 JSON 里properties.name不一致。典型情况是数据源里写的是“广东”,JSON 里是“广东省”,对不上,颜色就上不去。

排查办法是在setOption前打印出 JSON 里所有区域的名称:

console.log(chinaJson.features.map(f => f.properties.name));

然后跟你的 data 做对比。对不上的统一改成一致就行。这里建议以 JSON 文件里的name为准,因为那是渲染的基准。

6.3 地图渲染出来了但是有杂线/区块异常

出现杂线通常是你用的 JSON 文件格式不干净,或者坐标系投影导致边界错乱。遇到这种情况,可以先换一个数据源试试。如果所有数据源都这样,检查是不是浏览器兼容问题(老版 Safari 对大型 JSON 解析有时会异常),换 Chrome 试一下。

另一种情况是:你用的是 TopoJSON 格式但直接当成 GeoJSON 传给registerMap了。这两个格式完全不同,TopoJSON 的边界是编码压缩过的,必须先用topojson-clientfeature方法解压,不能直接用。如果你发现自己的文件里有arcs字段,那肯定是 TopoJSON,不是 GeoJSON。

6.4 地图在 Vue/React 中多次切换数据不更新

框架集成时容易遇到一个怪问题:第一次渲染正常,换一批数据后地图不变。这是因为 ECharts 的setOption默认是合并配置,不是全量替换。如果你的data数组从 30 个省份变成 5 个省份,那些没有被新数据覆盖的省份还保留旧值。

解决办法是在二次更新时加上notMerge参数:

chart.setOption(newOption, true);

如果还是不行,试试先chart.clear()setOption。另外,Vue 最好在nextTick之后再初始化图表,否则容器还没有真实宽高,图表会画不出来。

6.5 JSON 文件太大加载慢

完整的中国地图 JSON(区县级)可能有好几 MB,首次加载会卡顿。优化方式有两种:

一是做数据简化,推荐用mapshaper这个免费工具,在浏览器里上传 JSON,设置简化比例(比如 0.1%)输出,可显著降低文件体积。简化后边界会有一点变形,但肉眼基本看不出来。

二是改成按需加载,比如用省级图就只加载省级 JSON,别把区县级的全量数据引入。

6.6 地图文字标签重叠严重

省名或市名文字挤在一起,尤其在西南省份密集区域。解决方式:在label里关闭重叠检测,或者自定义formatter,只对关键区域显示标签:

label: { show: true, formatter: params => { const importantNames = ['北京市', '上海市', '广东省']; return importantNames.includes(params.name) ? params.name : ''; } }

这种方法在实际项目中很实用,既保留了重点区域的信息,又不至于让标签糊成一团。

7. 一点个人经验之谈

做了这么多年可视化,地图算是坑最多的一类图表,但坑的原因大都一样:数据源不稳、格式不对、坐标系混乱。我的建议是,地图 JSON 文件最好在项目里单独建一个目录管理,记录下载时间、数据来源、坐标系、简化比例,形成一份数据资产的台账。这样遇到问题能快速追溯到源头,而不是每次都靠猜。

另外,DataV 的数据源虽然好,但它的name字段有些是简称(比如“内蒙古”),有些是全称(比如“黑龙江省”),不同版本之间不完全统一。如果你要做存档或者长期维护,建议拿到 JSON 后先统一规范化一遍字段和名称,再投入使用。别看这一步琐碎,真到上线时候能省下很多事。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 11:17:54

Claude Code团队共享池落地实践:配置、网关与多端接入全记录

开头先说结论:Claude Code 这个工具,个人用很简单,装个命令行、配个 Key 就能跑;但一旦要放进团队,事情就完全变了。我们 Evol 团队从“人人各自装一套、配置千奇百怪”到搭起一个团队共享池,前后花了四周。…

作者头像 李华
网站建设 2026/9/9 11:17:03

ONVIF协议与RTSP拉流实战:从设备发现到视频渲染的完整链路

简介:针对ONVIF设备端(NVT)与OnvifDeviceManager对接时RTSP视频流无法正常拉流的典型问题,这份轻量级C代码包面向具备一定ONVIF与RTSP基础的嵌入式或网络视频开发者,提供作者验证通过的对接实现作为参照。压缩包内仅含…

作者头像 李华
网站建设 2026/9/9 11:16:27

从BUG终结者挑战赛看程序员调试能力:赛题设计与踩坑复盘

我到现在还记得那个周末的晚上,邮箱里躺着一封标题为“决赛判题结果申诉”的邮件。发件人是个参赛选手,他坚持认为自己在 BUG 终结者挑战赛里的提交被误判了,而且语气非常笃定。我当时心想,坏了,多半又是赛题环境出了问…

作者头像 李华
网站建设 2026/9/9 11:13:59

RetroArch BIOS 整理指南:从缺失报错到搭建可校验的固件库

简介:面向复古游戏玩家和模拟器爱好者,这是版本2020-11-02的仿真平台BIOS整合包,适用于RetroArch、RetroPie、RecalBox、Lakka、EmulationStation等主流复古游戏前端。整合包收集了大量libretro运行所需的系统、固件或BIOS文件,解…

作者头像 李华
网站建设 2026/9/9 11:13:40

计算机单片机毕设实战-基于 STM32 或 51 单片机的多传感器环境感知与自动调控装置设计 基于 STM32 或 51 单片机的室内环境阈值报警与蓝牙监控系统设计(017907)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/9 11:12:56

工控单板Linux存储规划与OverlayFS恢复出厂实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华