简介:ECharts中国地图JSON文件合集,面向需要实现地理数据可视化的前端开发者、数据分析和可视化学习者,解决在ECharts中绘制省级、市级、区县级区域地图时缺少边界数据与行政区划编码映射的痛点。压缩包共424个文件,全部为json格式,整体大小7.96MB,内容覆盖全国各省、市、区县地图所需要的GeoJSON边界数据,可配合ECharts的registerMap注册地图,并在series中通过type:'map'进行渲染。资源已有3349人学习下载,实用性得到一定验证。文件按行政区划编码命名,包含全国总图和各省份、地市的独立文件,目录结构清晰,便于按需取用;坐标系基于经纬度,可直接绑定业务数据完成数值映射、颜色分级与下钻交互。无论是搭建全国性数据大屏、区域经济报表,还是开发地理信息展示页面,这套合集都能显著减少整理地理数据的成本,帮助读者更专注于图表配置、数据表现与交互细节打磨。 搞前端可视化的人,迟早都会撞上中国地图JSON这个文件。ECharts本身不自带中国地图数据,想要在页面上渲染一个可交互的省份地图,就绕不开这份以JSON格式存储的地理边界数据。把它搞明白了,地图组件、visualMap分段、3D地图这些玩法也就都通了。这篇文章我就把中国地图JSON从拿到手、校验、注册、配数据,到踩坑排查的完整流程拆开讲一遍,适合刚接触ECharts地图、或者被地图JSON搞到烦的开发者直接参考。
1. 为什么中国地图必须配JSON文件
1.1 地图渲染的基本逻辑
ECharts的地图本质上是一张“矢量图”,不是图片。它通过解析GeoJSON格式的坐标点,把每个省、市、县的边界用多边形绘制出来。ECharts原生支持的地图只有世界地图和几个基础示例,并没有内置中国地图数据,所以你必须主动注册一份符合规范的地理数据文件,告诉ECharts“每个省份的边界长什么样、叫什么名字”。之后再结合series-map或geo组件,才能把数据值映射到对应区域上。
这个设计和做游戏先要加载模型资源很像:地图JSON就是那个“模型”,省名叫“id”,边界点就是“顶点坐标”。没有它,ECharts只是画了一个空白画布,即使有series数据也不知道往哪块区域上画。
1.2 JSON文件里到底存的什么
打开一份中国地图JSON,表面看是一大串坐标数组,实际上结构非常固定。最外层是一个对象,包含type和features两个关键字段。features是一个数组,每个元素代表一个省级行政区,内含properties和geometry。properties里通常有name(省份名称)和adcode(行政编码);geometry则定义了该省份的边界类型和coordinates坐标点集合。
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "name": "广东省", "adcode": 440000 }, "geometry": { "type": "MultiPolygon", "coordinates": [...] } } ] }ECharts注册地图时,主要靠properties.name和坐标点来生成可交互的图形。name是连接数据和地图的桥梁,你的series.data里每一项的name必须和JSON里的name完全一致,否则数据匹配不上,区域会显示为空白。坐标点则是绘制边界的核心,经度和纬度按顺序排列组成多边形环,多个环组合成完整的省界。
2. 中国地图JSON的获取与校验
2.1 常见获取渠道
网上流传的中国地图JSON文件版本很多,有的边界过时,有的坐标缺失,有的文件里混入了非法字符。我自己比较推荐以下几个渠道,稳定性和规范性都有保障:
- 阿里云DataV.GeoAtlas:可以按省、市、县下载对应的GeoJSON文件,数据更新及时,结构干净,适合直接用于ECharts。
- ECharts官方示例仓库:GitHub上apache/echarts仓库的map目录或相关示例资源中有标准中国地图JSON,适合离线项目。
- 第三方维护的china.json仓库:搜索“china geojson”能找到不少,但下载后一定要自行校验。
不建议直接去某些小型博客找“整理好的下载包”,因为那些文件可能被二次加工过,属性名改过、坐标精度丢失,甚至region层级不对。宁可花两分钟下载官方数据,也别在调试上浪费两小时。
2.2 用代码校验JSON是否合格
拿到JSON文件后,不要急着往项目里塞,先在Node或浏览器控制台里快速验证一下结构。最简单的方式是用JSON.parse检查能否正常解析,再检查features数组是否存在,并打印第一条数据的name和geometry类型。
fetch('china.json') .then(res => res.json()) .then(data => { console.log('解析成功'); console.log('features数量:', data.features?.length); console.log('第一个区域名称:', data.features?.[0]?.properties?.name); console.log('geometry类型:', data.features?.[0]?.geometry?.type); }) .catch(err => console.error('JSON格式错误', err));如果解析失败,说明文件里有语法错误、多余逗号或编码问题。常见的坑是文件用了BOM头,导致JSON.parse直接报错。处理办法是用编辑器或脚本去掉BOM:jsonData.replace(/^\uFEFF/, '')。另外还要确认geometry.type是Polygon还是MultiPolygon,这两种在ECharts里都能渲染,但如果你后续要做自定义绘制,就得分别处理。
3. 在ECharts中加载中国地图JSON的完整流程
3.1 注册地图与基础配置
ECharts 5版本中,注册地图使用echarts.registerMap('china', geoJson)。注册之后,就能在geo组件或series-map中通过map: 'china'引用这份地图数据。注册动作必须在setOption之前完成,否则ECharts会提示找不到地图。
import * as echarts from 'echarts'; import chinaJson from './assets/china.json'; echarts.registerMap('china', chinaJson); const chart = echarts.init(document.getElementById('mapContainer')); chart.setOption({ geo: { map: 'china', roam: true, itemStyle: { areaColor: '#e8e8e8', borderColor: '#ffffff' } } });这里我用了geo组件而不是series-map,原因在于geo更轻量,适合纯展示地图或作为背景图层。如果要把数值数据映射到省份颜色上,推荐使用series-map,因为它的数据和visualMap联动更自然。项目里常见做法是geo负责底图,series-map负责数据层,两者叠加实现类似高亮和散射点一起展示的效果。
3.2 给省份加数据:从“空白地图”到“数据地图”
注册好地图后,下一步就是把业务数据填进去。series-map的data是一个对象数组,每个对象至少包含name和value两个字段。
chart.setOption({ series: [{ type: 'map', map: 'china', roam: true, label: { show: true }, data: [ { name: '广东', value: 100 }, { name: '浙江', value: 86 }, { name: '江苏', value: 92 } ] }] });这里最容易被坑的是省份名称的写法。JSON里可能写的是“广东省”,而你数据里写的是“广东”,少一个字就匹配失败。我建议从JSON文件里动态读取省份名称来生成数据映射,而不是手写省份列表。可以先用一个map整理JSON里的名称和业务数据的对应关系:
const nameMap = { '广东省': '广东', '浙江省': '浙江' // 按需补充 };虽然麻烦,但一劳永逸,尤其省市联动时特别稳。
3.3 visualMap分段设色:怎么把9段改成10段
让地图看起来像专业数据大屏的关键就是visualMap分段。ECharts默认的visualMap可以是连续型,也可以是分段型。很多模板默认显示9段,想改成10段,关键在于分段数组的长度和max值设置。
visualMap: { type: 'piecewise', min: 0, max: 100, splitNumber: 10, pieces: [ { min: 0, max: 10 }, { min: 10, max: 20 }, { min: 20, max: 30 }, { min: 30, max: 40 }, { min: 40, max: 50 }, { min: 50, max: 60 }, { min: 60, max: 70 }, { min: 70, max: 80 }, { min: 80, max: 90 }, { min: 90, max: 100 } ] }如果只写了splitNumber: 10,ECharts会根据min/max自动均分区间,视觉上确实分了10段。但如果你用了pieces数组,就会以pieces为准,splitNumber会被忽略。所以最可控的办法是直接定义10个pieces区间,每个区间的颜色通过inRange.color数组一一对应。颜色数组长度和pieces长度最好一致,否则ECharts会自动插值,颜色可能不符合预期。
3.4 地图上的标签与标记数量
在地图上给某些市标记数量,本质是利用label或markPoint显示额外信息。如果你只是想让省份名称旁边显示数字,直接用label.formatter即可。
label: { show: true, formatter: function(params) { return params.name + '\n' + (params.value ?? ''); } }如果要在特定城市上放一个圆点并标注数量,需要用scatter系列叠加在地图上方。具体做法是设置一个散点系列,coordinateSystem指定为geo或map,data里的坐标用城市的经纬度表示。
series: [{ type: 'scatter', coordinateSystem: 'geo', data: [ { name: '广州', value: [113.26, 23.13, 56] }, { name: '杭州', value: [120.15, 30.28, 88] } ], symbolSize: function(val) { return Math.max(val[2] / 10, 8); }, label: { show: true, formatter: '{b}' } }]地理坐标需要提前准备好。注意经纬度数组的格式是[经度, 纬度, 数量],别写反了。我在实际项目中就经常看到有人把经纬度调换,结果标记点散到地图外面,花了好长时间才排查出来。
4. 常见报错与排查技巧实录
4.1 地图区域渲染为空白
现象是地图有边框,但内部颜色是空白或只有背景色。原因通常是series.data里的name与JSON里的properties.name不一致。比如JSON里是“广西壮族自治区”,数据里写“广西”,匹配不到就默认不渲染那块区域的颜色。解决办法是先打印JSON中的前几个name,再用模糊匹配或完整名称对齐数据。
另一个隐藏原因是JSON的坐标系问题。有些GeoJSON用的是非标准坐标系,ECharts默认只支持经纬度坐标。如果你拿到的JSON是投影坐标(比如Web Mercator平面坐标),渲染出来就会全部偏离或空白。碰到这类文件,直接换一个标准经纬度版本最省事。
4.2 JSON加载失败
最典型的表现是控制台报错Failed to fetch或Unexpected token < in JSON at position 0。前者是路径问题,说明文件没被正确访问;后者是请求结果不是JSON,可能是返回了HTML错误页面。常见诱因是使用webpack或vite时没有正确处理JSON文件。
Vite里直接import chinaJson from './assets/china.json'就能拿到对象,不需要额外配置。Webpack 5则需要在module.rules里确保json文件不被当作资源类型处理,或者直接使用import并开启jsonModules特性。还有一点要留意,项目部署后服务器要能返回.json文件的正确MIME类型,否则也会被浏览器拦截。
对于本地调试Edge浏览器加载本地JSON受限的问题,最方便的方式是开一个本地静态服务,比如npx serve,不要直接双击HTML文件打开。这是开发环境最常见的安全限制,不是代码问题。
4.3 边界缺失或岛屿显示不全
中国地图JSON通常包含海南、台湾以及南海诸岛等区域。如果你采用的JSON是从第三方下载,可能缺少部分岛屿数据,导致展示不完整。ECharts并没有自动补充岛屿的能力,只能靠JSON文件本身的数据完整性。
建议直接用阿里云或官方示例的数据,同时检查properties里是否包含“海南”“台湾”等名称。如果你看到地图下方没有南海诸岛的缩略小图,那就是文件里根本没有这个区域。正规的中国地图JSON应包含南海诸岛,具体是否显示小图取决于数据文件是否包含对应feature以及你的geo布局区域设置了多大的显示范围。
4.4 Vue/React中引用echarts的坑
在Vue项目里使用ECharts地图,最容易踩的坑是组件销毁时没有调用dispose,导致图表实例重复创建,出现“DOM元素已存在”的警告。还有一点是注册地图的全局污染问题。registerMap是全局API,注册后即使组件销毁,地图数据依然在内存中。多次注册同名地图会覆盖旧数据,一般不会有问题,但要小心异步加载JSON后重复注册,可能造成组件内图表重新渲染时引用到旧地图数据。
React中的问题更多集中在useEffect依赖数组上。如果setOption被多次调用,而JSON还没加载完,就会报“map not found”。稳妥做法是先把JSON加载并注册完,再初始化图表和设置option,整体放一个Promise链里。
对于uniapp或小程序环境,需要注意ECharts的运行环境是否支持DOM。通常要用canvas渲染模式,并且JSON需要通过import或本地静态资源引用,直接fetch在小程序里可能受平台网络限制。
5. 进阶:3D地图、性能优化与资源扩展
5.1 用echarts-gl实现geo3d和map3d
普通2D地图已经不能满足大屏需求时,很多项目会引入echarts-gl做3D地图。核心思路是使用map3d系列或geo3D组件,配合scatter3D实现城市点位立体展示。
加载方式类似,先用echarts.registerMap注册中国地图JSON,然后在geo3D或series-map3d中指定map: 'china'。
import 'echarts-gl'; chart.setOption({ geo3D: { map: 'china', shading: 'lambert', regionHeight: 2, itemStyle: { color: '#3a7fd4', opacity: 0.85 }, label: { show: true } }, series: [{ type: 'scatter3D', coordinateSystem: 'geo3D', data: [ { name: '北京', value: [116.4, 39.9, 10] } ], symbolSize: 5 }] });这里的regionHeight是控制省份“长高”的关键参数,值越大立体感越强。scatter3D的数据格式同样是[经度, 纬度, 高度或数值]。要注意,geo3D和map3D的渲染对浏览器性能有一定要求,如果省份数量多或区域边界面数大,建议关闭rotate动画或减小regionHeight。
5.2 大JSON的压缩与按需加载
中国地图完整JSON通常不到1MB,但如果是全国省市区级的全量数据,体积会明显增加,影响首屏加载速度。按需加载是最实用的优化手段:首屏只下载省级边界JSON,用户下钻到某个省时再动态请求对应市级JSON。ECharts支持多次registerMap,所以完全可以做到“用什么注册什么”。
还可以用JSON.stringify压缩掉多余空白,或者用pako对GeoJSON做gzip压缩,请求时解压后注册。这套方案在移动端特别有效。我自己负责的一个项目就是把全国地图JSON压缩后从230KB降到约50KB,加载速度提升了一倍多。
5.3 JSON结构如何配合“饼图/柱状图”动态联动
热词里有“echarts饼图”“柱形异形图”等内容,这里补充一个常见的联动场景:点击地图上的省份,下方饼图切换为该省份的城市数据。实现方式是在地图的click事件中捕获params.name,再根据省份名称过滤业务数据,更新另一个图表的option。
chart.on('click', function(params) { const provinceName = params.name; updatePieChart(provinceName); });这种联动最大的好处是复用同一份业务数据源,只需要维护好省份名称映射关系。地图JSON在这里起到的作用就是“点击区域定位到省份”的桥梁。类似的思路也能用于树图、箱线图等复杂组件,本质都是把地图选中的信息传递给其他图表实例。
6. 关于中国地图JSON的一些个人实操体会
做地图可视化这几年,我最大的感受是:地图JSON本身不难,难在数据一致性和边界情况处理。很多人花最多时间调试的地方不是ECharts的API,而是省份名称对不上、JSON文件编码有问题、或者地图数据不规范。如果你准备把地图能力沉淀成公共组件,建议一开始就把JSON文件抽离成一个独立配置模块,统一维护名称映射、adcode映射和视觉参数,这样后续接业务数据会顺畅很多。
最后分享一个小技巧:把中国地图JSON放在静态服务器后,不光能用ECharts加载,还能用原生JavaScript解析出每个省份的bbox(外接矩形范围)。利用这个信息可以自己做省份级别的居中定位,比如点击某个省后自动把geo组件的center移动到该省中心,并调整zoom实现下钻效果。这个功能不需要echarts-gl,纯原生API就能做,效果却很加分。目前网上很多“地图下钻”方案依赖额外的插件,其实只要有标准的JSON文件,自己实现下钻逻辑反而最可控,也最容易按项目需求定制。
本文还有配套的精品资源,点击获取