甘肃省市级地图数据包:ECharts GeoJSON离线可视化实战

发布时间:2026/10/18 19:48:53
甘肃省市级地图数据包:ECharts GeoJSON离线可视化实战 简介面向Web开发者与数据可视化初学者的甘肃省市级地图数据包内含全省14个市州精确轮廓边界可直接接入ECharts等常见地图库解决网页端展示行政区划地图时缺少坐标数据的痛点。包体共41个文件压缩后仅2MB其中21个JS文件包含echarts.min.js、jquery.js等绘图依赖与各省市地图注册逻辑19个JSON文件以GeoJSON格式存储各市边界坐标与经纬度数据另附1个HTML示例页面。示例以北京市地图演示完整调用流程开发者可参照其结构快速替换为甘肃省数据同时针对本地预览时的跨域限制提示火狐通常可直接打开、Chrome需借助本地服务器或CORS代理运行资源内已给出相应解决思路。已有651人学习下载资源体量小、目录清晰、开箱即用适合快速搭建省级市级地图展示、可视化大屏或GIS教学练习也可作为ECharts地图组件学习的配套素材省去自行整理地理数据的繁琐步骤。1. 甘肃省市级地图JS数据包拆开一份本地可渲染的GeoJSON地图资源做数据大屏最怕的不是没数据而是地图数据只有省级轮廓想落到市一级就抓瞎。这份甘肃省市级地图JS数据包把甘肃全省的各市轮廓做成了js和json两套格式同时给了一个用北京市地图演示的完整HTML样例——你拿到手之后把地图名从「北京」换成「甘肃省」一个离线可跑的地市级地图页面就出来了。它适合正在做区域可视化大屏、不想依赖在线地图服务的开发者也适合想搞懂ECharts地图注册机制和浏览器跨域限制的前端新手。2. 资源包拆解js与json双格式的目录设计与GeoJSON数据结构2.1 解压后的目录结构与双文件格式分工zip解压后核心内容是「1」这个目录里面有演示页、js目录和json目录。我解压之后整理出的文件结构大致是这样的路径作用北京.html演示页加载北京地图并渲染出完整页面js/echarts.min.jsECharts核心库负责地图绘制和交互js/jquery.jsDOM操作与ajax请求的辅助库js/北京市.js北京市地图数据script标签引入后可直接使用js/甘肃省.js甘肃省市级边界数据是这份资源的核心js/天津市.js、js/重庆市.js、js/上海市.js其他直辖市样例数据json/北京市.json北京市数据JSON格式版json/甘肃省.json甘肃省数据JSON格式版json/天津市.json、json/重庆市.json、json/上海市.json其他直辖市JSON格式版这里最值得琢磨的是为什么每个地名都要给两份格式。.js文件里的内容通常是一条赋值语句类似 window[北京市] {...}用script标签引入之后全局对象上直接就挂了一个同名的GeoJSON变量不需要发请求、不需要处理回调页面打开的那一瞬间数据就在内存里了。.json文件则相反它是纯粹的文本数据必须靠fetch、XHR或者jQuery的$.getJSON去读取这一读就引入了跨域和异步问题。我一般会在两种场景下做区分交付离线demo或者一个不会频繁变动的静态报表时优先用.js方案省事且稳项目里地图数据需要定期更新、或者由后端接口下发时用.json方案更合适因为数据和服务分离更新时不用重新发前端包。两种格式同时提供正好覆盖了这两类最常见的落地场景。关于跨域这件事第一次接触这个包的人容易有误解以为js和json只是格式差异随便选一种都行。实际差别在浏览器安全策略上script标签加载外部脚本不受同源策略限制所以file协议下可以正常打开而fetch和XHR请求file路径在Chrome和绝大多数现代浏览器里都会被拦截报错信息通常是 CORS policy: Cross origin requests are only supported for protocol schemes。这就是资源包里特别备注「建议用火狐打开谷歌请参考跨域解决方案」的原因——火狐对本地file页面加载本地json的限制比Chrome宽松一些但宽松不等于没有第4章我再展开每种浏览器的差异。2.2 GeoJSON里的轮廓数据从coordinates到城市边界打开js/甘肃省.js你会发现整个文件的核心是一个FeatureCollection结构大致是这样的{ type: FeatureCollection, features: [ { type: Feature, properties: { name: 兰州市 }, geometry: { type: MultiPolygon, coordinates: [ [ [ [103.6, 36.0], [103.8, 36.1] ] ] ] } } ] }这段代码里的坐标点是我简化的示意实际文件里每个市至少几十个点围成边界有些地市面积大、边界复杂几百上千个点都很正常。关键是理解coordinates的嵌套层级最外层是「多个多边形」的组合因为一个市可能有大块陆地加几块飞地飞地必须单独用一组点来描述第二层是「一个闭合多边形的环」环上的点按顺序相连最后一个点会自动闭合成起点最内层的 [经度, 纬度] 才是真正决定市界位置的数据。从开发角度讲你不需要手改这些坐标但要知道两个常识。第一properties.name 是地图能否正确显示城市名的关键字段ECharts会拿它和 series.data 里的 name 做匹配名字写错一点tooltip和visualMap就全对不上。第二这些坐标绝大多数来自公开行政区划数据源坐标系是GCJ-02还是WGS84在文件本身看不出来需要采样校验这一点在第4章坑里我再详细说。2.3 echarts.min.js与地图渲染的离线优势这个包里体积最大、最核心的运行时是echarts.min.jsjquery.js只是辅助。ECharts的地图渲染机制和Leaflet、Mapbox那类基于瓦片的在线地图完全不同它不请求任何瓦片服务而是完全依赖你通过registerMap注册进去的GeoJSON对象去绘制矢量轮廓。所谓registerMap本质上是把你提供的FeatureCollection翻译成ECharts内部可以绘图的坐标网格。注册完之后series里声明 map: 甘肃省图表的渲染器就会从这个网格里找出对应的多边形路径画在canvas或者SVG上。整条链路里没有网络请求、没有底图版权问题、没有在线服务的账号配置所有数据都在本地。这个离线特性在实际交付中非常有用。给客户做演示时不会因为对方会议室网络差就白屏部署到内网环境也不需要跟外网有任何往来。缺点同样明显没有路名、没有POI、没有地形只能拿来做区域轮廓和业务数值的可视化不适合做地图导航类应用。知道这个边界你才不会在错误的地方用它。3. 核心实现拆解从北京样例到甘肃省市级地图的替换链路3.1 北京.html的加载流程与script引入策略包里的北京.html是一个最简可运行的demo。这类数据js文件的常见写法是往window上挂全局变量所以页面骨架大致长这样!DOCTYPE html html head meta charsetutf-8 / title北京市地图/title script srcjs/echarts.min.js/script script srcjs/jquery.js/script script srcjs/北京市.js/script /head body div idmap stylewidth: 800px; height: 600px;/div script var chart echarts.init(document.getElementById(map)); echarts.registerMap(北京, window.北京市); chart.setOption({ series: [{ type: map, map: 北京 }] }); /script /body /html加载顺序有个讲究echarts.min.js必须最先引入因为它是运行时jquery.js在demo里主要承担辅助工作北京市.js最后引入因为它的内容是一条赋值语句等它执行完window上才有北京市这个全局变量。三个script都放在head里的写法在本地demo没问题真正做项目时我一般会把业务脚本挪到body底部避免DOM还没渲染完就去init容器。registerMap(北京, window.北京市)这一行有两个参数需要分清楚第一个参数是「注册名」是给ECharts内部用的标识跟文件名、跟GeoJSON里的properties.name都没关系第二个参数才是真正的GeoJSON对象。这意味着 registerMap(北京, window.北京市) 和 registerMap(beijing_map, window.北京市) 都能工作只要series.map里的字符串和注册名保持一致就行。3.2 地图注册与series配置的完整参数说明上面demo是最简配置实际项目里要跑通一份「能看、能点、能展示数据」的地图series的配置项通常会多一些。下面是一份我常用的完整配置var myChart echarts.init(document.getElementById(map)); // 注册地图第一个参数是注册名第二个参数是GeoJSON对象 echarts.registerMap(甘肃省, window.甘肃省); myChart.setOption({ title: { text: 甘肃省市级地图, left: center, textStyle: { fontSize: 18 } }, tooltip: { trigger: item, formatter: function (params) { return params.name br/数值 (params.value || 暂无数据); } }, visualMap: { type: continuous, min: 0, max: 100, left: 10, bottom: 20, text: [高, 低] }, series: [{ type: map, map: 甘肃省, roam: true, label: { show: true, fontSize: 10 }, itemStyle: { borderColor: #fff, borderWidth: 1 }, data: [ { name: 兰州市, value: 86 }, { name: 天水市, value: 72 } ] }] });逐项说一下参数含义。title.text是图表标题left: center让它居中显示属于纯展示配置。tooltip.trigger: item表示鼠标悬浮到某个地图块上时触发提示formatter里的params.name是鼠标所在市的名称params.value来自series.data中同name对应项的value值。visualMap是颜色映射组件配置了min和max之后地图块会根据data里的value大小从浅到深着色业务指标越高颜色越深数据大屏上几乎必配。series里的type: map告诉ECharts要渲染地图系列map: 甘肃省对应registerMap时的注册名roam: true允许鼠标滚轮缩放和平移label.show控制城市名直接显示在行政块中央itemStyle.borderColor设置相邻城市边界的颜色和粗细。关键点在于data数组里每一项的name必须和GeoJSON中properties.name完全一致value则是你要展示的业务指标。如果data缺了某个城市这个城市依然会被画出来只是不参与visualMap配色显示为默认底色。这个行为常被误认为是bug其实是ECharts的既定设计。3.3 最小改动三处替换完成省级地图切换把北京样例改成甘肃省市级地图只需要改三处。第一处是把HTML里引用的 script srcjs/北京市.js 换成 script srcjs/甘肃省.js第二处是把 registerMap(北京, window.北京市) 换成 registerMap(甘肃省, window.甘肃省)第三处是把 series[0].map 从 北京 改成 甘肃省。第四处要改的是data数组里的城市名。北京各区县名和甘肃各市名完全对不上需要换成甘肃的市名例如data: [ { name: 兰州市, value: 235 }, { name: 天水市, value: 295 }, { name: 酒泉市, value: 105 } ]这三处替换的价值在于你不需要重新理解任何API不需要改样式和交互逻辑整套ECharts的tooltip、visualMap、roam能力原封不动继承下来。这就是为什么样例用北京而数据用甘肃时项目仍然足够落地——它展示的是整个可以迁移的调用范式而不是某一张静态图。4. 避坑指南跨域、编码与坐标系不一致的5个典型现场4.1 Chrome双击HTML地图空白file协议下的跨域限制现象用Chrome直接双击打开北京.html页面框架出来了但地图区域一片空白F12控制台报域名跨域的错误关键词通常是 Cross origin requests are only supported for protocol schemes。原因Chrome对file://页面的本地资源访问限制很严格尤其当页面内部用fetch或XHR去读取其他本地文件时会被同源策略直接拦下。demo页面里引了jquery.js常见写法就是通过$.getJSON去读json数据这一读就撞在跨域墙上。解决最快的办法是按包内提示改用火狐打开火狐对本地file页面读json的限制相对宽松要不就在目录里起一个静态服务在终端进入目录执行 python3 -m http.server 8000然后访问 http://localhost:8000/北京.html 。这个方案我后面会反复用它能把本地文件访问变成http访问跨域问题直接消失。4.2 火狐能开但城市名乱码Meta字符集缺失现象火狐能打开页面地图轮廓也正常但城市名显示成乱码中文全变成「鐪椾笢鍖?」之类的字符。原因js和json文件里的中文是按UTF-8编码的但HTML页面没有声明字符集时浏览器会按系统默认编码去解析脚本内容在中文Windows上通常就是GBK中文字符全错位。这个问题很隐蔽因为页面不报错只有文字是花的。解决在HTML的head最上方加上 一行就解决。如果加了还乱码多半是编辑器把js文件另存时转成了GBK或ANSI编码把文件重新另存为UTF-8无BOM格式即可。以后拿到任何地图数据文件我第一步都是先确认编码省得后面查半天。4.3 渲染成功但业务数据点集体漂移坐标系混用现象地图轮廓渲染完全正常但用经纬度往地图上叠加散点或markPoint时点全部飘到海里或者偏移几百米到几公里。原因这是坐标系不一致的典型表现。市县级GeoJSON边界数据如果来自国内在线地图平台多半是GCJ-02坐标系而GPS设备返回的经纬度是WGS84。两种坐标系在经度跨度大的区域偏移量会非常明显叠加的点看起来就像集体「跳海」。解决先确认GeoJSON数据源是什么坐标系再决定是否转换。WGS84转GCJ-02是固定算法的过程网上有标准实现反过来GCJ-02转WGS84要用迭代逼近。这里有个实用判断如果只做轮廓展示不叠加业务点坐标系差异可以完全无视一旦要在图上叠加任何定位数据这一步绕不开。4.4 加载json文件直接白屏file页面下的fetch限制现象把原来的script标签改成 $.getJSON(json/甘肃省.json, function(){...}) 之后火狐下正常Chrome下直接白屏控制台报错说跨域请求被阻塞。原因火狐允许本地file页面读取同目录下的本地文件Chrome则完全不允许。同一个包、同一份代码两种浏览器表现完全不同这正是包内备注「建议用火狐打开谷歌请参考跨域解决方案」的真实场景。解决在http服务环境下跑或者把json内容手动包成js文件用script标签加载。如果一定要保留json格式又想本地跑可以写一个动态创建script的加载器让服务端返回一个callback包裹的JS也就是经典的JSONP思路。生产环境我更推荐直接起服务json走正常接口请求这样数据更新、缓存、错误处理都更可控。4.5 tooltip显示不出城市名data的name与地图name不匹配现象地图画出来了visualMap也生效了但鼠标悬浮到某个市上时tooltip里没有城市名只有一行数值甚至数值都没有。原因series.data里的name和GeoJSON中properties.name写法不一致比如数据里写的是「兰州」而GeoJSON里是「兰州市」又或者混入了空格、全角字符。ECharts的匹配是严格相等差一个字都匹配不上。解决检查两边的name是否严格一致最稳的办法是从GeoJSON里把城市名取出来打印出来逐一对齐var mapData window.甘肃省; var cityNames mapData.features.map(function (f) { return f.properties.name; }); console.log(cityNames);项目做多了你会发现90%的地图显示疑难杂症最后都是这种不起眼的字段匹配问题跟渲染引擎本身没关系。先验name再查跨域最后才去怀疑数据坐标这个排查顺序能省大量时间。5. 跑通与改造把本地样例升级成你的第一个甘肃省市级可视化页面5.1 三步跑通解压、定位、打开第一步解压zip得到外层目录第二步确认北京.html和js目录、json目录在同一层不要单独把html文件挪出来第三步用火狐直接双击北京.html能看到北京市的完整轮廓说明环境正常这份资源里的数据文件和ECharts库都没有问题。如果这一步白屏按第4章的顺序去排查先看控制台有没有跨域报错再确认HTML头部有没有meta charset最后看script标签的路径是否指向正确。html用的是相对路径所以html和js目录的相对位置不能变挪动html后所有路径都要跟着改。习惯用命令行的同学我建议直接在目录内起一个本地服务cd 1 python3 -m http.server 8000然后在Chrome或火狐里访问 http://localhost:8000/北京.html 。这一步能同时验证两件事本地服务环境下json和js两种数据格式都能加载成功后续你用fetch去读json也不会踩跨域坑。这个命令执行完终端会挂着不退出属于正常现象。5.2 替换数据从北京换成甘肃省各市的完整步骤沿用前面说的三处替换完整的页面代码可以精简成下面这样!DOCTYPE html html langzh-CN head meta charsetutf-8 / title甘肃省市级地图/title script srcjs/echarts.min.js/script script srcjs/甘肃省.js/script /head body div idmap stylewidth: 100%; height: 600px;/div script var chart echarts.init(document.getElementById(map)); echarts.registerMap(甘肃省, window.甘肃省); chart.setOption({ tooltip: { trigger: item }, visualMap: { min: 0, max: 100 }, series: [{ type: map, map: 甘肃省, roam: true, data: [] }] }); /script /body /html注意这里我把jquery.js的引用去掉了因为demo没用到它少引一个文件页面加载更快。替换之后你可以先不填data地图本身就能渲染出甘肃各市轮廓并显示市名这证明甘肃省.js这个数据文件没问题问题只可能出在后续的业务数据上。第二步再填业务数据。以人口数据为例var population [ { name: 兰州市, value: 324 }, { name: 嘉峪关市, value: 31 }, { name: 金昌市, value: 43 }, { name: 白银市, value: 151 }, { name: 天水市, value: 335 } ]; chart.setOption({ series: [{ type: map, map: 甘肃省, data: population }] });setOption会自动和之前的配置合并不需要重新init和registerMap。赋了value的市会按visualMap的区间显示颜色深浅没赋值的保持默认底色。这个特性在做「部分城市重点标注」的时候很好用比如只标有数据的市其他市留白。5.3 两种引用方式的取舍script同步 vs json异步同一份数据在包里给了js和json两种载体实践中怎么选我的判断标准很简单页面只展示一次地图、数据固定、发布到内网用script同步引入js就够了。全局变量加载即用没有异步时序问题也没有跨域请求被拦截的风险。如果地图数据要由后端接口按需下发或者边界数据后续要更新建议用json方案配合HTTP请求。比如$.getJSON(json/甘肃省.json, function (geoJson) { echarts.registerMap(甘肃省, geoJson); var chart echarts.init(document.getElementById(map)); chart.setOption({ series: [{ type: map, map: 甘肃省 }] }); });这种写法把地图数据和业务代码彻底分离以后换数据源时只改后端返回的json内容前端一行不用动。代价是必须在HTTP服务环境下运行file协议下Chrome会拦截这个请求火狐相对宽容。总的来说我的习惯是demo和离线交付走js正式系统走json接口。6. 二次开发技巧封装一个兼容js与json的通用地图加载器6.1 从裸调用到工程化一个loadMap函数当项目里有多个页面都要展示不同省的地图把script标签写死在HTML里就会很痛苦。这时候我会做一层封装把「加载GeoJSON 注册地图」收敛成一个函数function loadMap(mapName, callback) { // 如果全局对象上已经有这份地图数据直接回调避免重复加载 if (window[mapName]) { callback(window[mapName]); return; } // 否则动态创建script标签加载js文件绕开跨域限制 var script document.createElement(script); script.src js/ mapName .js; script.onload function () { callback(window[mapName]); }; script.onerror function () { console.error(加载地图数据失败 mapName); }; document.head.appendChild(script); } loadMap(甘肃省, function (geoJson) { echarts.registerMap(甘肃省, geoJson); renderMap(甘肃省); }); function renderMap(mapName) { var chart echarts.init(document.getElementById(map)); chart.setOption({ series: [{ type: map, map: mapName, roam: true }] }); }这个加载器兼容了两种使用姿势window上已有数据时直接回调避免重复创建script标签没有时动态插入script不依赖jquery、不依赖HTTP服务本地file协议下也能工作。以后新加一个省的地图只需要把js文件丢进js目录然后 loadMap(某省, ...) 即可页面代码不用再动。把这个思路再往前推一步你可以把业务数据和地图数据彻底解耦地图只用loadMap注册业务指标单独从接口拉两者都就绪后再setOption。这样地图渲染和数据变更互不阻塞做省级下钻到市级的大屏时尤其顺手。从那以后我每次搭地图类项目都强制先画一遍这个加载器的调用关系再动手写业务。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询