eCharts地图资源:344个县区GeoJSON与两种加载方式详解

发布时间:2026/10/19 8:00:27

eCharts地图资源:344个县区GeoJSON与两种加载方式详解 简介面向需要在中国县级行政区划层面做数据可视化的前端开发者这份eCharts地图资源提供了全国344个县区的可复用地图数据并内置两种接入方式演示直接使用预置地理数据集以及加载外部JSON自定义地图。压缩包共391个文件其中380个为JSON格式的县区边界与代码数据另含6个JavaScript脚本、2个HTML示例页面、2个工程配置文件及1份docx说明整体仅2.82MB便于快速下载与接入项目。目前已有1552人学习或下载适合正在搭建区域统计、人口经济指标展示或需要离线地图方案的初中级开发者参考。通过配套Demo可快速理解echarts.init、setOption等关键步骤掌握地图配准、下钻与悬浮交互的落地写法JSON数据按县区拆分为独立文件可按需引用省去自行爬取边界数据的成本。1. 县级地图的“最后一公里”这份 344 县区 eCharts 资源解决的是什么问题做过数据大屏或区域分析项目的开发者大多有这个体会eCharts 官方地图免费开放到市级一旦想下钻到区县能直接用的地图资源就突然变得很稀薄。要么找到的 GeoJSON 覆盖不全要么坐标系偏了导致元素错位要么数据格式不统一没法直接喂给 eCharts。这份“eCharts 地图 344 个县区附带两种方式 demo”的资源包恰好填的是这个断层——它一次性给出 344 个县区的地图数据并且用两种不同加载方式写了可直接运行的示例。适合正在做区县级数据可视化、需要地图下钻、或者想快速验证“某个县区数据落在图上什么位置”的前端开发者。2. 资源包解剖344 个县区地图数据长什么样2.1 目录结构与文件清单拿到资源包先别急着跑建议先把目录结构过一遍。通常这类地图资源会按“数据”和“示例”两个维度组织在一棵目录树里常见布局如下echarts-map-344-counties/ ├── data/ │ ├── geojson/ │ │ ├── 110101.json # 每个文件对应一个县区 │ │ ├── 110102.json │ │ └── ... │ ├── merged/ │ │ └── all_counties.json # 合并后的完整数据 │ └── countyList.json # 行政编码、名称对照表 ├── demo/ │ ├── demo-local.html # 方式一本地加载 demo │ ├── demo-async.html # 方式二异步加载 demo │ └── assets/ │ └── echarts.min.js # 已内置的 echarts 库 └── README.md # 数据说明与使用文档这里的关键是data/geojson下的文件命名方式——用行政区划代码做文件名是行业惯例好处是天然唯一、不会重名而且可以轻易通过countyList.json把代码映射成中文名。merged/目录里的合并文件则省去了你自己写合并脚本的麻烦。demo/assets下已经放好了 echarts 的压缩版意味着你不装任何依赖也能直接打开 HTML 看到效果。2.2 数据格式GeoJSON 里都有哪些字段探讨这份数据之前先花半分钟回顾一下 eCharts 对地图数据的消费方式。eCharts 的地图系列map类型不直接吃 GeoJSON 原始结构它要求先通过echarts.registerMap注册地图注册时内部会提取 GeoJSON 里的features数组把每个 feature 的properties.name作为地图区域的名称标识。所以这份资源里每个县区的 GeoJSON 文件都是标准结构核心字段如下{ type: FeatureCollection, features: [ { type: Feature, properties: { name: 某县, adcode: 110101, center: [116.4, 39.9] }, geometry: { type: MultiPolygon, coordinates: [...] } } ] }properties.name就是地图上显示的区域名务必跟你业务数据里的区县名保持完全一致。properties.adcode是行政区划代码这是数据联动的关键字段做下钻、点击事件、数据匹配时都优选它做关联键。geometry是真正的边界形状数据MultiPolygon意味着一个县区可能有多个不相连的面比如某个县有飞地或者包含岛屿渲染时 eCharts 会自动把多个面合并显示。2.3 数据规模与坐标系说明344 个县区这个数字意味着什么对比一下全国县级行政区划总数接近 2800 个这份资源覆盖的是其中一部分但 344 个的数量级足够支撑大多数区域分析类项目。更重要的是这份数据已经做了坐标系统一处理——常见的坑是各区县数据来源不一有的用 WGS84、有的用 GCJ-02混合加载时会出现边界错位甚至跑到海上。从文件大小看每个县区的 GeoJSON 在 20KB 到 200KB 之间取决于边界复杂度344 个文件合计大概是 30MB 到 80MB 的量级。这个规模给两种加载方式都留出了工程空间本地直接注册适合数据一次性全量加载异步合并加载则适合控制首屏速度或者做主从地图切换。3. 方式一本地注册 GeoJSON一个 main.js 跑通3.1 核心代码读取 GeoJSON 并注册到 eCharts方式一的思路非常直接把需要的县区 GeoJSON 文件在页面加载时全部读取然后逐个调用echarts.registerMap注册最后在图表配置里通过map: 某县区名指定渲染哪一个。下面这段代码是从 demo-local.html 里提炼出的完整主流程// 1. 引入本地的 echarts 和县区数据按需列出你要用的 const echarts require(./assets/echarts.min.js); const countyData require(./data/countyList.json); const geojsonMap { 110101: require(./data/geojson/110101.json), 110102: require(./data/geojson/110102.json) }; // 2. 遍历注册地图 Object.keys(geojsonMap).forEach(adcode { const geo geojsonMap[adcode]; const name geo.features[0].properties.name; echarts.registerMap(name, geo); }); // 3. 初始化图表并渲染指定县区 const chart echarts.init(document.getElementById(map-container)); chart.setOption({ series: [{ type: map, map: 某县, // 对应上面注册时的 name roam: true, label: { show: true }, data: [ { name: 某县, value: 358 } ] }] });逻辑说明第 1 步用 CommonJS 的require方式拉取本地文件这是 webpack 或浏览器打包环境下最常见的写法如果你直接用script标签引入把require换成全局变量读取即可。第 2 步是核心registerMap的第二个参数必须是完整的 GeoJSON 对象函数会读取features[].properties.name作为区域名这就是为什么名字必须和业务数据一致。第 3 步设置map: 某县时echarts 会在已注册的地图中查找同名地图并渲染roam: true开启缩放拖拽这是县级地图几乎必开的功能因为单县边界细节多用户需要缩放查看。3.2 渲染配置地图初始化与 visualMap 联动有一说一单纯的县区边界图意义不大实际项目里更多是往地图上叠数据做可视化。资源包的方式一示例里还带了一段visualMap配置这能把数值映射成不同的颜色深浅让数据分布一眼可见chart.setOption({ visualMap: { min: 0, max: 500, left: 20, bottom: 20, inRange: { color: [#e0f3f8, #abd9e9, #74add1, #4575b4, #313695] } }, series: [{ type: map, map: 某县, data: [ { name: 某县, value: 358 } ] }] });参数说明visualMap.min和max决定颜色映射的数值区间超出区间的值会被钳制到端点颜色inRange.color是一个颜色数组数值从小到大对应数组从左到右实际项目中建议根据业务场景调整配色比如用红绿渐变表示正负值。这里我一般会踩一个坑——数据里的name是中文全称比如“某县”如果地图注册名是简称比如“某”匹配就会失败整个县区直接不渲染。所以要养成在data数组里填写 GeoJSONproperties.name完整值的习惯。3.3 适用场景与改造要点方式一最适用的场景是单县区或者少量县区的展示比如某个县的人口热力图、某个区县的 GDP 分布、或者固定区域的疫情数据看板。它的优点是代码量少、逻辑直观、不需要处理异步竞态浏览器打开即渲染没有任何网络请求延迟。改造时常见的两个方向一是把require替换成远程 http 请求获取 GeoJSON适合地图数据统一存放在 CDN 或后端的场景二是把data数组替换成从接口拉取的业务数据核心就是保持name或adcode能和 GeoJSON 里的属性对应上。如果业务上需要同时展示多个临近县区更推荐用方式二的合并策略下面详细说。4. 方式二异步加载与按需合并适合平台化项目4.1 核心代码Promise 加载 344 个文件之后合并方式二解决的核心问题是 344 个文件不能一次性全部注册——否则浏览器有几百个地图对象占内存页面卡顿。更合理的做法是先用一份县区清单渲染一个总览地图可以是省级轮廓用户点击某个县时再去加载对应 GeoJSON 并注册渲染。demo-async.html 里的思路就是异步按需加载核心逻辑如下// 1. 准备一个加载函数输入 adcode返回注册好的地图名 async function loadCountyMap(adcode) { const res await fetch(./data/geojson/${adcode}.json); const geo await res.json(); const name geo.features[0].properties.name; if (!echarts.getMap(name)) { // 避免重复注册 echarts.registerMap(name, geo); } return name; } // 2. 根据区县 id 动态渲染 async function renderCounty(adcode, value) { const mapName await loadCountyMap(adcode); chart.setOption({ series: [{ type: map, map: mapName, data: [{ name: mapName, value }] }] }); } // 3. 初始化时先展示某个默认县区 renderCounty(110101, 358);这段代码最值得注意的就是echarts.getMap(name)的存在性检查。如果没有这一步用户反复点击同一县区时会重复注册同名地图——echarts 虽然后注册的同名地图会覆盖前一个但这一过程会有短暂的白屏和重新渲染开销。fetch返回的res.json()是异步的用await挂起保证拿到完整 GeoJSON 再注册避免后续渲染时找不到地图。这种方式下344 个文件只有被访问到的才会进入注册池内存占用大幅下降。4.2 性能参数加载策略与缓存从工程上看异步加载只是第一步真正让 344 个县区可用的关键是配套的缓存策略。demo-async.html 在代码注释里提到一种常见做法——用fetch加上接口层的 HTTP 缓存或者在 JavaScript 层做 Map 缓存减少重复请求// 用 JavaScript Map 做一级缓存避免重复 fetch const geoCache new Map(); async function loadCountyMap(adcode) { if (geoCache.has(adcode)) { return geoCache.get(adcode).name; } const res await fetch(./data/geojson/${adcode}.json); const geo await res.json(); const name geo.features[0].properties.name; echarts.registerMap(name, geo); geoCache.set(adcode, { name, geo }); return name; }参数说明geoCache以adcode为键存储已加载的 GeoJSON 引用下一次点击同一县区时直接从内存取请求时间为零。这里的适配成本很低——如果你的项目用的是 axios 而不是 fetch把请求函数替换掉即可。对于数据量级更大的场景还可以在 HTTP 层设置Cache-Control: max-age86400让浏览器缓存 GeoJSON 响应这样即使刷新页面也不需要重新下载边界数据。两种缓存叠加之后344 个县区的资源包在真实业务里基本感受不到重复加载的延迟。4.3 两种方式的对比与选择建议对比维度方式一本地全量注册方式二异步按需加载首屏速度慢所有县区一次加载快只用加载默认县区内存占用高注册全部地图对象低仅已访问县区代码复杂度低同步逻辑中涉及 async/await适合场景单县展示、内网工具页地图下钻、平台级应用工程扩展性弱加县区要改代码强按 adcode 随意切换我的建议是如果你的项目只是一个固定的县区看板比如某高校要做校内数据可视化展示用方式一足够如果做的是面向多区域的平台系统需要用户在不同县区间切换查询方式二是更稳妥的架构。方式二踩坑的地方主要在于异步时序——用户在快速切换县区时前一个setOption还没执行完后一个就来了解决办法是用一个简单的请求序号只让最后一次请求更新图表let requestSeq 0; async function renderCounty(adcode, value) { const seq requestSeq; const mapName await loadCountyMap(adcode); if (seq ! requestSeq) return; // 已有新请求放弃本次结果 chart.setOption({ /* ... */ }); }这段代码虽然只有三行但解决了一个很影响体验的翻车点——用户连续点击 A 县、B 县时如果 A 县的加载时间比 B 县长则 A 县的渲染结果可能后到并覆盖 B 县加了序号判断后过期请求自然丢弃。5. 避坑指南画县级地图最容易翻车的四个地方5.1 坑一地图区域不显示控制台也没有报错现象setOption执行后地图区域空白series 数据也没报错但页面就是什么都不渲染。原因90% 的概率是map: 某县的字符串和registerMap注册时的名字不一致——比如注册时用的properties.name值是“某某县”而这里写成了简称“某某县”另一个原因是 GeoJSON 内部的properties缺失或字段名不是name导致 eCharts 无法识别区域名。解决打印geo.features[0].properties看实际字段可以在注册前用console.log(name)验证一下也可以通过echarts.getMap(某县)查询该地图是否注册成功返回undefined就说明名字对应不上。血泪教训这种问题通常是静默失败的建议在renderCounty里加一层判断找不到地图时主动抛错而不是让人盯着空白的画布发呆。5.2 坑二地图位置偏移到海里或者和底图错位现象地图渲染出来了但位置明显不对有的跑到海外有的县界和相邻县重叠。原因GeoJSON 的坐标系不统一。标准地理数据用 WGS84GPS 原始坐标系而部分在线获取的数据经过 GCJ-02 加密偏移两种混用就会导致错位。这份 344 县区资源基本已统一但如果你二次开发时混入外部数据这个问题立刻暴露。解决所有输入的地图数据尽量从同一来源获取且优先选择标注“WGS84”或“CGCS2000”的数据。如果确实混入了 GCJ-02 的数据可以写一个小工具做坐标转换再合并。这里我一般会用proj4库做投影转换但考虑到项目体量不大时直接放弃该数据源往往更省成本。5.3 坑三数据 name 匹配不上地图上所有区域一个颜色现象地图能渲染但所有区域颜色相同visualMap似乎没生效。原因series.data数组里的name值与 GeoJSON 里的区域名对不上时eCharts 会把该数据项丢弃视觉上就是所有区域都落入默认色。这是县级地图最常翻车的地方因为各区县命名习惯不统一——有的叫“xx区”有的 GeoJSON 里叫“xx城区”差一个字就匹配失败。解决统一用adcode做匹配是一个好办法让后端接口返回adcode而不是名称前端数据进入series.data时通过countyList.json把adcode映射成正式名称从根上消掉命名偏差。如果数据端改不了就建一个别名映射表在渲染前把历史数据里的“xx老城区”“xx新城区”清洗成标准名。5.4 坑四344 个 GeoJSON 全部注册后页面卡顿现象一次性把 344 个县区全部registerMap后页面滚动和缩放明显掉帧打开开发者工具发现内存占用很高。原因一个 GeoJSON 少则几十 KB多则几百 KB全部解析后浏览器需要保存几百个地图对象及边界坐标数组内存和渲染引擎都无法承受。解决回到第 4 章的异步按需加载方案除了默认展示的县区外其余全部在用户交互时才注册。如果你的场景真的需要首屏展示 344 个区域最好的方式不是逐个注册而是把 344 个 GeoJSON 合并成一个FeatureCollection注册一张总地图。资源包的data/merged/all_counties.json就是为这个准备的第 6 章接入测试时我会详细演示合并注册的写法。6. 二次开发从“344 县区”到“任意区县下钻”的改造实践6.1 改造思路把静态资源变成可配置的地图服务拿到这份资源包我第一个动手的方向是做一个“省份 → 区县 → 边界详情”的三级下钻模块。原始 demo 把 344 个县区和特定业务的耦合太紧改造的目标是抽出一层独立的地图加载服务。核心思路用一份县区清单countyList.json驱动地图层级点击上级区域时按需加载下级边界业务数据通过adcode关联而不依赖名称。// 地图加载服务负责数据获取和注册对外只暴露 render 方法 const CountyMapService { cache: new Map(), async ensureLoaded(adcode) { if (this.cache.has(adcode)) return this.cache.get(adcode); const res await fetch(./data/geojson/${adcode}.json); const geo await res.json(); const name geo.features[0].properties.name; if (!echarts.getMap(name)) echarts.registerMap(name, geo); this.cache.set(adcode, name); return name; }, async render(adcode, bizData) { const mapName await this.ensureLoaded(adcode); const chart this.chart; chart.setOption({ visualMap: { /* ... 配置 */ }, series: [{ type: map, map: mapName, data: [{ name: mapName, value: bizData.value || 0 }] }] }); } };这个改造把地图的“数据加载”和“业务渲染”解耦了后续接任何业务只需要在bizData上做文章。有一点值得注意文件名的adcode在资源包里统一是 6 位数字而业务接口常返回的是省市区带连字符的编码比如“110101”和“110101-001”需要提前把非标准格式转换掉否则请求直接 404。6.2 验证方法用随机数据做一次下行链路测试改造完别急着接真实业务先用一段随机数据验证整条链路是通的。我习惯的做法是写一个小的自测页面遍历countyList.json中的 10 个县区逐个调用CountyMapService.render观察地图是否都有边界出图、数据点是否落在对应区域。代码大致是这样// 自测随机取 10 个县区依次渲染验证 const sample countyList.slice(0, 10); for (const county of sample) { const ok await CountyMapService.render(county.adcode, { value: Math.random() * 500 }); if (!ok) console.warn(渲染失败: ${county.name}); } // 检查 echarts 内部已注册地图数量 console.log(已注册地图数:, Object.keys(echarts.getMap()).length);这个验证环节能帮你快速排查三类问题文件路径是否匹配、GeoJSON 是否能被正常解析、注册名是否能被 map 配置引用。等验证通过后再接真实业务数据基本就能把排查范围缩小到数据本身。从那以后我每次做地图类项目都强制走一遍这个流程——先随机样本验证地图链路再接业务数据这个习惯帮我躲过了至少 5 次因数据命名不统一引起的返工希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/19 8:00:27

narrator-ai-cli:一句话生成影视解说视频的自动化实践

做影视解说做了三年多,我一直在跟剪辑软件、配音工具、文案平台打交道。说实话,一套视频做下来,最耗时间的根本不是剪辑本身,而是文案打磨、配音录制、字幕对齐这些细碎活。前阵子朋友给我推荐了一个命令行工具,名字叫…

2026/10/19 7:55:27

前端性能优化实战:用Chrome Performance面板精准定位卡顿与长任务

1. 从“感觉卡”到“定位卡”:Performance面板到底在解决什么问题前端性能优化这件事,最怕的不是问题难,而是根本不知道问题出在哪。我见过太多同行,页面一卡就开始猜:是不是图片太大了?是不是接口太慢了&a…

2026/10/19 7:55:27

3D U-Net自适应医学图像分割:从数据流水线到测试时调整

初次在项目台账里看到“DL00658”这个编号时,我心里第一反应是,这应该又是一次普通的数据实验存档。等翻到推理日志和训练配置,才发现它是一套完整跑通的“自适应医学图像分割”方案。所谓自适应,不是模型在训练结束后就万事大吉&…

2026/10/19 9:15:58

海康WebControl插件接入RTSP视频流的网页实时播放方案

1. 项目背景与核心问题拆解1.1 为什么需要WEB播放器方案先说结论:如果你要在网页里实时播放海康摄像头的RTSP视频流,直接用HTML5的video标签是行不通的。原因很简单,主流浏览器早就放弃了RTSP协议的原生支持,再加上H.264编码的视频…

2026/10/19 9:15:58

开放式代码审查实战:从工具链到团队协作的完整方案

1. 为什么说“开放式代码审查”值得单独开一个项目来做先说结论:open-code-review 不是一个简单的“请同事帮忙看看代码”的流程说明,它是一整套围绕“公开、透明、可追溯”的代码审查实践方案,涵盖了工具链搭建、审查规范制定、团队协作机制…

2026/10/19 9:15:58

AI驱动问卷设计:结构化生成与人工校验的实践指南

做问卷调研这些年,我越来越确信一件事:问卷没设计好,后面所有统计手段都只是补救。很多人觉得问卷设计就是“把想问的事情写成选择题”,等数据回收回来才发现,题目有歧义、选项有遗漏、跳转逻辑混乱、量表锚点不统一&a…

2026/10/19 9:15:58

SpringBoot+Vue+MySQL在线招投标系统毕业设计全流程实战指南

每年毕业设计的题目清单里,“在线招投标系统”几乎是稳定出现的面孔。这个题目的经典之处在于:它不冷门、不缺业务场景、难点可控,而且 SpringBoot Vue MySQL 这套组合本身就是不少同学简历里反复出现的技能栈。如果你正在纠结毕业设计选什…

2026/10/19 9:15:58

代码审查自动化实践:构建智能规则引擎,告别无效Review

做代码审查这件事,我在团队里忍了很久。表面上看我们在严格执行 Pull Request 流程,每个 PR 都有人点 Approve,但实际上有一大半 review 只是“LGTM”刷屏;真正认真看逻辑的少之又少,低级错误照样漏到线上,…

2026/10/19 9:10:57

无人机公路缺陷巡检:YOLOv8数据集构建到部署全程解析

无人机公路缺陷巡检,这个项目一干就是三个月。从最初带着设备在高速路边战战兢兢地调试,到后面形成一套完整的“采集—标注—训练—部署”闭环流程,中间踩过的坑比想象中要多得多。这套YOLO数据集(编号第10051期)沉淀下…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/19 0:04:56

悟空开源无代码平台实战:从实体建模到应用设计避坑指南

简介:基于悟空开源无代码平台的多种应用设计源码,面向希望在不编写代码的情况下快速搭建CRM、HRM、财务系统、ERP、SRM等业务应用的企业与技术人员,通过拖放式界面和内置模板即可完成应用定制与部署。压缩包共697个文件,约10.74MB…

2026/10/19 0:04:56

基于.NET9的多租户权限系统:数据权限与动态API落地实践

简介:这份资源是一套面向 .NET 与 Vue 全栈开发者的中台权限管理系统,后端基于 .Net9,前端采用 Vue3 Element Plus,并配套 uniapp uviewui 移动端方案,实现前后端分离。系统覆盖多租户隔离、数据权限、动态 Api、任务…

2026/10/19 0:04:56

场地预约小程序毕设实战:SSM+微信小程序+MySQL数据库设计到避坑

简介:面向毕业设计场景的场地预约小程序完整项目,基于微信小程序SSMMySql技术栈开发,适合计算机相关专业学生作为选题参考、功能扩展或二次开发起点。系统实现场地类型管理、场地管理、预约管理、取消申请与押金退回等功能,分为管…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑