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

发布时间:2026/9/9 11:18:02
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字段里有name、adcode、center等信息。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 项目先安装 EChartsnpm 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.type是mapmap字段填的是registerMap时自定义的字符串。data数组中的name字段必须与 JSON 中properties.name一一对应对不上就显示不出来。visualMap负责图例和颜色映射。type是piecewise还是continuous取决于业务需求。分段型适合少数几个区间对比连续型适合数值梯度较平滑的场景。4.4 让地图自适应容器大小地图画完后浏览器窗口改变大小图不会自动跟着变需要监听 resize 事件window.addEventListener(resize, () { chart.resize(); });在 Vue 组件中记得在onUnmounted里移除监听并调用chart.dispose()释放实例避免内存泄漏。4.5 处理偏远岛屿等小区域显示问题中国地图有个经典问题南海诸岛默认在地图右下角以插图形式展示但有时候你放大南海区域会发现它是一块空白。这个问题通常是数据源导致的DataV 的全国 JSON 里南海诸岛是包含在图内的但 ECharts 渲染时默认的视角可能没把它显示全。解决办法是在series里设置center和zoom来控制地图的显示范围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系列配合geo3D、scatter3D组合使用。这里贴一段简化版的代码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里做。比如你要展示某个城市的数值就在scatter3D的data里给出该城市的经纬度和大小这样点会悬浮在 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 } ] }]如果你用的底图是全国 JSONname就对应省份名称。所以你的数据粒度决定了你用哪份 JSON别拿省级数据配全国底图那是对不上的。5.3 visualMap pieces 调整分段从 9 段变 10 段热词里有一条很具体echarts visualmap pieces和echarts地图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注册。排查顺序检查echarts.registerMap(china, data)是否在setOption之前执行。检查registerMap的第一个参数是否和series.map的值一致。检查 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-client的feature方法解压不能直接用。如果你发现自己的文件里有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 后先统一规范化一遍字段和名称再投入使用。别看这一步琐碎真到上线时候能省下很多事。本文还有配套的精品资源点击获取