省市地图边界GeoJSON获取与ECharts集成指南

发布时间:2026/9/9 2:13:40
省市地图边界GeoJSON获取与ECharts集成指南 简介资源提供全国各省市地图边界坐标数据包面向需要在地图上绘制行政区划边界的前端与数据可视化开发者可直接用于常用地图组件免去手工整理坐标点的繁琐流程。包内共36个文件其中35个JSON格式坐标文件分别对应各省、市、自治区及港澳台地区的边界数据另含1个JS文件便于页面加载与配置压缩包整体仅415KB轻量易集成结构简洁、命名清晰。每个JSON采用FeatureCollection结构包含区域编号、名称、中心点及多边形边界点序列例如北京市密云县的边界数据可直接渲染出完整区域轮廓开发者无需再做数据清洗。目前已有2479人学习下载适合快速搭建行政区划地图、制作地理数据可视化大屏或开展地图类前端练习能明显缩短底图数据准备时间也适用于教学演示与项目原型开发。 做可视化开发的人迟早会遇到一个绕不开的需求画中国地图、省份地图、城市地图。但地图边界这种东西总不能靠手绘一条条线去描。所谓中国各省市地图边界坐标 json 文件本质上就是把每个省、市的地理边界用经纬度坐标点串起来存成结构化的 json 数据最常见的载体就是 GeoJSON。这类文件支撑起了 ECharts 注册地图、Leaflet 绘制图层、各种大屏项目的省份高亮、区域下钻、散点聚合等功能是前端可视化和数据分析链路里最基础也最关键的一环。这篇文章不是丢给你一个网盘链接就完事而是把找数据→清洗→转换→集成→排错整条链路完整过一遍。我会从数据结构讲起给出可直接用的代码示例和处理工具再把我实际踩过的坑整理成排查清单。适合刚开始接触地图可视化的前端开发者、数据分析师也适合已经被地图数据反复折腾过的同学查漏补缺。1. 先想清楚边界坐标 JSON 到底解决什么问题1.1 为什么不能直接拿地图图片凑合很多人第一反应是直接切一张中国地图的 PNG 图片放进页面不就完了确实静态展示完全没问题但一旦涉及交互就露馅了你要点击某个省份高亮、要在地图上叠加业务数据、要根据数据大小动态调整区域颜色、要放大后边界依然清晰——位图全部做不到。图片放大就糊、区域无法单独响应事件、数据变化就得重新切图这种维护成本根本没有上限。矢量边界数据则是另一套玩法。每个省、市的边界是由一串经纬度坐标点连成的闭合多边形前端拿到这些坐标后实时渲染成图形。用户在图上点击你得到的是用户点到了哪个省这个结构化信息而不是用户点到了图片的哪个像素。数据侧想给某个省标一个数值只需要把数值和省的名称或者编码对齐。所有交互、联动、缩放都变成纯前端逻辑这才是地图可视化该有的能力边界。1.2 GeoJSON 的数据结构到底长什么样市面上各省市边界 json 文件绝大多数遵循 GeoJSON 规范。这个格式本身不复杂核心就是一个嵌套的 json 数组结构我拆开讲。最外层通常是 FeatureCollection要素集合里面有一个 features 数组数组里每个元素对应一个省或一个市。每个 feature 由两部分组成properties 里存属性信息比如省名、城市名、行政区划代码geometry 里存实际的边界坐标。{ type: FeatureCollection, features: [ { type: Feature, properties: { name: 广东省, adcode: 440000 }, geometry: { type: MultiPolygon, coordinates: [ [ [ [113.5, 23.5], [114.2, 23.8], [114.8, 24.1] ] ] ] } } ] }这里有两个新手最容易卡住的点。第一坐标顺序是经度在前、纬度在后也就是 [longitude, latitude]写成 [经度, 纬度]和日常口语里北纬23.5度、东经113.5度的顺序正好相反很多人在这里掉过坑。第二geometry 的 type 可能是 Polygon 也可能是 MultiPolygon如果一个行政区域存在飞地、岛屿或者边界被切割成多块就会用 MultiPolygon。coordinates 的嵌套层级也因此不同Polygon 是四层数组MultiPolygon 是五层。搞清楚这个层级你在写代码遍历坐标做简化或者转格式时才不会乱。2. 数据获取现成文件哪里来又该怎么筛2.1 常见数据源对比市面上的省市级边界数据来源不少但质量和更新频率差异很大。我整理了几个常用的渠道按推荐程度排一下。数据源获取难度数据特点适用场景ECharts 官方地图数据低边界经过简化层级到市级体积小常规可视化项目、大屏展示DataV.GeoAtlas阿里云低按行政区划编码提供 json更新及时需要单独省份或城市数据时高德、天地图 API中数据准确度高但需申请 key 且有调用限制对边界精度要求高的 GIS 项目开源仓库GitHub 维护中数据质量参差不齐需人工验证二次加工追求可定制我个人的习惯是做标准可视化首选 ECharts 和 DataV 的数据因为它们本身就是为了前端渲染做过简化处理的坐标点密度适中直接拿来用不会让页面卡死。如果做 GIS 分析那宁可花时间申请高德或者天地图的接口拿原始数据虽然加工成本高一点但精度有保障。2.2 下载后第一件事检查数据质量拿到文件别急着往项目里塞先做三件事检查。第一看 properties 字段是否齐全重点是 name 和 adcode行政区划代码。name 用于和你的业务数据做匹配adcode 用于做下钻关联缺了任何一个后面都会很被动。第二检查坐标范围是否合理。中国范围内的经纬度经度大致在 73 到 135 之间纬度在 18 到 54 之间。如果你发现坐标里有几百上千的值十有八九是数据源坐标顺序反了或者经过了错误投影。第三确认边界是闭合的即每个多边形首尾坐标相同否则渲染时会出现裂缝。这些检查不需要写复杂脚本用 Node 跑个小循环或者直接在浏览器控制台 fetch 下来遍历一遍 coordinates 数组就行。花十分钟做检查能省掉后面一晚上的排查时间。3. 处理流程从原始数据到可上线的 JSON3.1 坐标点简化控制文件体积原始行政边界数据往往非常精细一个省级单位的边界可能包含上万甚至十几万个坐标点。直接放进前端json 文件轻松超过几兆浏览器解析和 Canvas 渲染都会明显卡顿。所以拿到数据后第一件事通常是简化也就是在不影响边界基本形状的前提下删掉多余的坐标点。常用的工具有 Mapshaper一个开源的地图数据处理工具支持命令行和网页版。它的核心命令是simplify跑一遍就能按比例减少坐标点数量。mapshaper china.json -simplify 1% -o china_simplify.json1%表示保留约百分之一的坐标点这个比例对省级地图来说通常能保持边界形状可辨认同时把文件体积缩小几十倍。实际使用中我会根据用途调比例只做省级填色1% 足够要做市级下钻建议保留 3% 到 5%因为市级边界更复杂缩得太多会变形。简化后务必人工扫一眼关键区域比如沿海线、省界交汇处确认没有出现明显的边界割裂或尖角。3.2 格式转换GeoJSON 不是终点GeoJSON 是最通用的格式但不是唯一的选择。不同渲染库对数据格式有各自的偏好常见的转换需求有三类。一类是 ECharts 支持的 GeoJSON 直接注册这个不用转后面会细讲。第二类是转成 TopoJSON它通过共享边界的拓扑关系来去重文件体积比 GeoJSON 更小适合大型地图数据但需要在渲染端额外引入topojson-client来解码。第三类是把 json 多边形坐标转成 SVG 的 path 路径用于静态矢量图输出。之前有读者问地图 json 转 svg 地图怎么做其实就是先读取 GeoJSON 的多边形顶点用墨卡托或等距投影把经纬度映射到平面坐标再拼成 SVG 的M、L、Z路径指令。命令行工具ogr2ogr可以完成多个格式之间的互转它支持 GeoJSON、Shapefile、TopoJSON 等几十种格式功能非常强大。不过对纯前端项目来说我更推荐在网络条件允许时直接用在线转换工具处理零散需求批量处理再考虑命令行。3.3 属性字段整理为下钻和联动铺路边界坐标只是骨架真正让地图活起来的是 properties 里的属性字段。我建议在数据清洗阶段就把字段统一整理好至少包含三级信息name名称用于展示和匹配、adcode行政区划代码用于树形下钻和接口关联、level省/市/区等级用于控制交互层级。有些数据源还带有childrenNum这样的字段表示下辖子区域数量做逐级下钻时非常有用。整理字段时要注意编码一致性问题。比如你的业务数据里写的是广东而地图数据里是广东省直接匹配必然失败。我的习惯是统一在数据预处理阶段把名称规范化或者干脆不用名称匹配全流程用 adcode 作为唯一关联键名称只用来显示。这个方法在市级下钻场景里尤其省心因为不同数据源对城市名称的写法五花八门。4. 在项目里真正跑起来4.1 ECharts 注册地图的完整示例ECharts 是前端做地图可视化最常用的库它本身不内置地图数据需要先用registerMap把 GeoJSON 注册进去。我给出一个完整的可运行示例。import * as echarts from echarts; // 1. 加载 json 文件 // Vite 环境可以直接用 ?url 引入或者用 fetch import const res await fetch(/maps/china.json); const geoJson await res.json(); // 2. 注册地图第二个参数就是 GeoJSON 对象 echarts.registerMap(china, geoJson); // 3. 初始化图表并配置 const chart echarts.init(document.getElementById(map)); chart.setOption({ geo: { map: china, roam: true, // 允许缩放拖拽 itemStyle: { areaColor: #e8e8e8, borderColor: #a0a0a0 } }, series: [{ type: map, map: china, roam: true, // data 里的 name 需要和 GeoJSON properties.name 一致 data: [ { name: 广东省, value: 120 }, { name: 浙江省, value: 98 } ], label: { show: true } }] });关键点有两个。一是注册名china是自己起的后面配置里的map字段必须和它一致。二是 series 的 data 中每一项的name要和 GeoJSON 的properties.name完全匹配否则对应的数据不会渲染到地图上而且 ECharts 不会报错只在控制台打一条警告很容易被忽略。4.2 省市级下钻的联动实现下钻的本质是切换注册的地图数据并重绘。用户点击某个省份我们加载该省的市级边界 json重新注册地图刷新图表。实现上需要额外监听点击事件。// 省级地图点击事件 chart.on(click, (params) { const adcode params.value?.adcode || getAdcodeByName(params.name); // 按需加载市级 jsonadcode 是省份编码的前两位 const cityGeoJson await loadMapDataByAdcode(adcode); echarts.registerMap(city, cityGeoJson); chart.setOption({ geo: { map: city }, series: [{ type: map, map: city, data: cityData }] }); });这里推荐按需加载而不是一次性加载全国所有市级地图。一个省动辄几十个市全部加载可能多出好几兆数据首屏体验很差。更合理的做法是维护一个映射表点击时根据省份 adcode 动态 fetch 对应的市级 json并用 Redis 或浏览器缓存做二次加载加速。返回上一级则重新注册省级地图即可逻辑对称不易出错。4.3 渲染性能优化地图卡顿的原因通常有三个坐标点太多、Canvas 重绘太频繁、多个图表实例同时存在。对应的方案也很明确。一是在数据侧做简化前面提到的 Mapshaper 就是干这个的我建议把简化写进数据处理的固定流程里而不是每次手动操作。二是关闭不必要的动画animation: false在某些高频交互场景下能明显提升帧率尤其是区域 hover 响应。三是复用图表实例不要每次数据变更都dispose再init那样会不断创建新 Canvas内存占用飙升。还有一个容易被忽视的点如果地图区域不需要点击事件就把series的silent设为true只保留geo组件的交互能减少事件绑定带来的开销。实测下来这些优化叠加起来对一个包含几百个区县的地图首屏渲染时间能压缩一半以上。5. 实战中踩过的坑5.1 地图区域不显示这是我在社区里被问到最多的问题。大部分情况是 json 没有成功注册。有人用fetch拿到了数据但忘记await有人把 json 文件放进了public目录却在src里 import还有人把geoJson对象传错给了registerMap。排查思路很简单在registerMap前后分别打印一下数据确认拿到的是对象而不是字符串。如果 json 是以字符串形式存在必须先JSON.parse再注册直接传字符串会导致渲染区域空白。5.2 区域错位、边界扭曲表现是地图整体位置不对或者某个省飞到了海里。多半是坐标顺序写反了GeoJSON 要求 [经度, 纬度]但有的数据源在生成时写成了 [纬度, 经度]。我处理过一份数据整体经度纬度数值调换后地图才正常显示。另一个常见原因是坐标系不统一GeoJSON 通常使用 WGS84 经纬度坐标但某些来源给的是 GCJ-02火星坐标系或偏转了若干米的坐标直接拿 WGS84 的地图底图去叠必然错位。遇到这种情况没有别的办法只能通过坐标纠偏接口或者专业工具把数据统一到同一套坐标系。5.3 JSON 解析失败与编码问题json 文件加载后解析失败常见原因有三个。一是文件里混入了 BOM 头JSON.parse会直接抛错处理办法是用文本编辑器另存为 UTF-8 无 BOM 格式。二是文件本身带了注释或者尾逗号这在某些手写的 json 里很常见但标准 JSON 解析器不认。三是文件过大导致fetch超时或内存溢出这时需要回到第 3 节做简化。另外有读者问过浏览器加载本地 json 文件被拦的问题这是因为浏览器的安全策略默认禁止页面跨域读取本地文件开发阶段可以起一个本地静态服务解决而不是直接双击打开 HTML 文件。我整理一个排查速查表方便大家对照。现象直接原因快速验证方法解决办法整块地图空白json 未正确注册打印 registerMap 前后数据确认数据是对象先 JSON.parse数据没渲染上name 与 properties 不匹配控制台查看 series 名称匹配警告统一用 adcode 关联或对齐名称边界错位坐标顺序/坐标系不对抽查一个坐标值范围交换经纬度或做坐标纠偏页面卡顿坐标点过多查看 json 文件体积Mapshaper 简化到 1%~5%解析报错BOM/注释/尾逗号用格式化工具重新保存另存为 UTF-8 无 BOM6. 关于数据维护的一些个人建议地图数据不是一次下载就能管一辈子的事情。行政区划调整时有发生比如某些地区升级、合并、更名如果不定期更新数据地图上的区域和你的业务数据会慢慢对不上。我现在的习惯是在项目里保留一份数据来源登记表记录每个 json 文件的获取时间、来源地址、坐标版本并在代码里通过 adcode 版本号做接口协商。这样即使某天数据源变更也能快速定位影响范围不至于上线后才发现某个区域的统计数字挂到了错误的位置上。另外一个心得是不要把地图数据硬编码进业务代码里尤其是市级、区县级这种会频繁更新的数据。把地图 json 独立成静态资源按adcode.json的方式命名由构建流程统一拷贝到静态目录既方便版本管理也方便后续单独更新不需要动业务代码重新发版。最后说一个很多人会忽略的细节做非浏览器端项目比如跨平台桌面应用时json 文件的读取路径不能用浏览器域的写法需要用文件系统 API 读取后转成字符串再解析。这两种环境下fetch的表现完全不一样我在迁移项目时被这个问题卡过两次提前封装一个统一的数据加载函数能省掉不少重复排错的时间。本文还有配套的精品资源点击获取