简介:这份资源面向地理信息开发、地图可视化与GIS教学研究者,提供覆盖全球国家边界的世界地图GeoJSON数据集,可用于构建交互式世界地图、开展地理空间分析或作为服务端地理信息API的数据基础。压缩包共约2000个文件,以3443个json文件为主,整体仅2.1MB,体积轻量便于快速加载与二次处理;文件按国家与地区拆分,包含国家整体边界及部分行政区、岛屿的独立几何数据,采用WGS84坐标系统,属性字段可承载国家名称、首都、人口等非几何信息。目前已有4730人学习下载,适合前端地图库集成、离线地图应用开发及教学演示等场景。读者可据此完成国家边界绘制、区域面积与数量统计、地理编码反编码等任务,并借助多环多边形结构处理岛屿与湖泊等复杂边界,是理解现代地理信息系统与地图服务原理的实用素材。
1. 世界地图 GeoJSON 数据包:从“能打开”到“能上线”的完整落地路径
做数据可视化或者 GIS 开发的人,迟早会撞上一个需求:把世界地图画出来,按国家填色,或者把业务数据挂到国家维度上。这时候你搜“世界地图 json 数据”,跳出来的结果十有八九是 GeoJSON。但下载完解压一看,一堆.json文件,有的几十 KB,有的几 MB,用文本编辑器打开是一坨坐标数组,用 ArcGIS 打开又报错——这就是典型的“资源在手边,但不知道怎么用”。这份世界国家 GeoJSON 数据包解决的就是这个问题:它把全球国家边界、各国独立地图文件整理成标准 GeoJSON 格式,可以直接喂给 ECharts、D3.js、Leaflet、Mapbox、ArcGIS、QGIS 这些工具。适合谁?做前端可视化但不想碰 shapefile 的工程师、做数据分析需要按国家聚合的从业者、以及需要离线地图底图的项目。下面我从数据本身讲到代码落地,再到踩坑排查,一步步拆开。
2. GeoJSON 到底是什么:和 shapefile、TopoJSON 的选型对比
2.1 为什么不是 shapefile,也不是 KML
GeoJSON 的本质是一个 JSON 对象,遵循 RFC 7946 规范,用FeatureCollection包裹一组Feature,每个Feature的geometry字段描述点、线、面,properties字段挂属性。和 shapefile 比,它最大的优势是纯文本、无二进制依赖、能被任何 JSON 解析器读取。shapefile 虽然生态成熟,但至少三个文件(.shp/.shx/.dbf)一起才能用,前端加载还得先转格式。KML 更偏向 Google Earth 场景,浏览器端解析库少。TopoJSON 是 GeoJSON 的压缩变体,用弧段共享减少体积,但可读性差,调试时打开文件根本看不懂。常见做法是:开发阶段用 GeoJSON 方便调试,上线前如果体积敏感再转 TopoJSON。
这份数据包里的文件命名通常按国家代码或国家名组织,比如world.geojson是全球国家面,china.geojson、usa.geojson是单国边界。每个 Feature 的properties里一般包含name、iso_a2、iso_a3这类字段,具体字段名取决于数据来源版本,用之前先打开一个文件确认。
2.2 坐标系:WGS84 是默认,但别假设
GeoJSON 规范规定坐标必须是 WGS84(EPSG:4326),经纬度顺序是[经度, 纬度]。这一点和很多国内地图 API 用的 GCJ-02 或者百度的 BD-09 不一样。如果你把这份 GeoJSON 直接叠到高德或百度地图上,边界会偏移几百米到几公里。这不是数据错了,是坐标系不匹配。解决办法有两个:一是用转换库把 GeoJSON 坐标从 WGS84 转到 GCJ-02,二是底图也用 WGS84 的瓦片(比如 OpenStreetMap)。我一般会先确认底图坐标系,再决定要不要转。
2.3 数据精度与体积的权衡
全球国家边界数据有多个精度版本,常见的有 1:110m(低精度,约 200KB)、1:50m(中精度,约 2MB)、1:10m(高精度,约 20MB+)。低精度适合全球概览,高精度适合单国放大。这份数据包如果包含多个精度文件,选型逻辑很简单:全球仪表盘用 110m,单国详情页用 50m 或 10m。别一上来就用最高精度,浏览器渲染几万个坐标点会卡。
3. 加载与渲染实战:ECharts、D3、Leaflet 三条路线
3.1 ECharts 注册地图并按国家填色
ECharts 是国内用得最多的可视化库,加载 GeoJSON 的方式是echarts.registerMap。下面是一个完整可跑的示例,假设你已经把world.geojson放在项目目录下。
// 引入 ECharts 和 GeoJSON 数据 import * as echarts from 'echarts'; import worldGeoJson from './data/world.geojson'; // 注册地图,'world' 是自定义地图名,后续 series.map 要用这个名字 echarts.registerMap('world', worldGeoJson); const chart = echarts.init(document.getElementById('map')); // 模拟业务数据:国家名要和 GeoJSON properties.name 对应 const data = [ { name: 'China', value: 100 }, { name: 'United States', value: 80 }, { name: 'Brazil', value: 60 } ]; chart.setOption({ tooltip: { trigger: 'item' }, visualMap: { min: 0, max: 100, inRange: { color: ['#e0f3f8', '#4575b4'] }, text: ['高', '低'], calculable: true }, series: [{ type: 'map', map: 'world', // 对应 registerMap 的名字 roam: true, // 允许缩放和拖拽 label: { show: false }, data: data }] });逻辑说明:registerMap把 GeoJSON 注册成一个地图对象,ECharts 内部会解析FeatureCollection并提取每个 Feature 的properties.name作为区域标识。series.data里的name必须和 GeoJSON 里的name完全一致,否则那个国家不会填色。参数方面,roam: true开启鼠标缩放,visualMap控制颜色映射,label.show在全球视图下建议关掉,否则国家名会挤成一团。
3.2 D3.js 投影与路径生成
D3 更底层,适合需要自定义投影或交互的场景。核心是d3.geoPath配合投影函数。
import * as d3 from 'd3'; import worldGeoJson from './data/world.geojson'; const width = 960, height = 500; // 使用 Mercator 投影,fitSize 自动缩放以适配画布 const projection = d3.geoMercator() .fitSize([width, height], worldGeoJson); const path = d3.geoPath().projection(projection); const svg = d3.select('#map') .append('svg') .attr('width', width) .attr('height', height); // 绘制每个国家 svg.selectAll('path') .data(worldGeoJson.features) .enter() .append('path') .attr('d', path) .attr('fill', '#ccc') .attr('stroke', '#fff') .attr('stroke-width', 0.5) .on('mouseover', function() { d3.select(this).attr('fill', '#4575b4'); }) .on('mouseout', function() { d3.select(this).attr('fill', '#ccc'); });逻辑说明:fitSize是 D3 v4 之后的方法,自动计算缩放和平移,让地图填满画布。geoPath把经纬度坐标转成 SVG 路径的d属性。参数上,geoMercator适合世界地图,geoEqualEarth或geoNaturalEarth1视觉更自然但计算稍慢。注意 D3 默认也是 WGS84,和 GeoJSON 一致。
3.3 Leaflet 叠加 GeoJSON 图层
Leaflet 是地图库,适合需要底图瓦片和交互的场景。
import L from 'leaflet'; import worldGeoJson from './data/world.geojson'; const map = L.map('map').setView([20, 0], 2); // 添加 OpenStreetMap 底图,WGS84 坐标系 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); // 添加 GeoJSON 图层 L.geoJSON(worldGeoJson, { style: function(feature) { return { color: '#fff', weight: 1, fillColor: '#4575b4', fillOpacity: 0.5 }; }, onEachFeature: function(feature, layer) { // 绑定点击弹窗,显示国家名 if (feature.properties && feature.properties.name) { layer.bindPopup(feature.properties.name); } } }).addTo(map);逻辑说明:L.geoJSON直接接受 GeoJSON 对象,style函数按 Feature 返回样式,onEachFeature用来绑定交互。参数上,setView的缩放级别 2 适合全球视图,fillOpacity控制透明度。注意 Leaflet 默认底图是 WGS84 的 OSM,如果换成国内底图需要处理坐标系偏移。
4. 数据裁剪与格式转换:从全球到单国,从 GeoJSON 到 TopoJSON
4.1 用 Python 按国家提取子集
有时候你只需要某个国家的边界,但数据包给的是全球文件。用 Python 的geopandas或者纯json模块都能做。下面是不依赖 geopandas 的纯标准库写法,适合环境受限的情况。
import json # 读取全球 GeoJSON with open('world.geojson', 'r', encoding='utf-8') as f: world = json.load(f) # 目标国家名,要和 properties 里的字段对应 target = 'China' # 过滤 FeatureCollection features = [ feat for feat in world['features'] if feat['properties'].get('name') == target ] # 构造新的 FeatureCollection result = { 'type': 'FeatureCollection', 'features': features } with open('china.geojson', 'w', encoding='utf-8') as f: json.dump(result, f, ensure_ascii=False) print(f'提取了 {len(features)} 个 Feature')逻辑说明:核心就是列表推导过滤features数组。参数上,properties.get('name')里的字段名要按实际数据调整,有的数据用NAME或admin。ensure_ascii=False保证中文国家名正常写入。如果数据量很大,可以用ijson流式解析,但一般全球文件几十 MB 以内,直接加载没问题。
4.2 用 mapshaper 做简化与格式转换
mapshaper 是一个命令行工具,能简化边界、转换格式、合并文件。安装方式常见的是npm install -g mapshaper。
# 把 GeoJSON 转成 TopoJSON,减少体积 mapshaper world.geojson -o format=topojson world.topojson # 简化边界,保留 10% 的顶点,大幅减小体积 mapshaper world.geojson -simplify 10% -o world_simplified.geojson # 按属性拆分,每个国家一个文件 mapshaper world.geojson -split name -o format=geojson output/逻辑说明:-simplify 10%使用 Visvalingam 算法简化,10% 是保留比例,数值越小文件越小但边界越粗糙。-split name按name字段拆分,输出到output/目录。参数上,简化比例建议先试 20%,看视觉效果再调整。注意简化后的坐标可能产生自相交,如果后续要做空间分析,慎用高比例简化。
4.3 在 ArcGIS 和 QGIS 中打开 GeoJSON
热搜里有人问“geojson 可以用 arcgis 打开吗”,答案是能,但方式要对。ArcGIS Pro 从 2.6 版本开始支持直接拖入 GeoJSON,ArcMap 则需要用“JSON To Features”工具或者 Data Interoperability 扩展。QGIS 更简单,直接把.geojson拖进图层面板就行。如果打开后看不到图形,先检查坐标系设置:QGIS 默认会识别 WGS84,ArcGIS 可能需要手动指定。另一个常见问题是属性表乱码,这是因为 GeoJSON 默认 UTF-8,而某些 ArcGIS 版本默认用系统编码,需要在导入时指定编码。
5. 避坑与排查:坐标系、属性字段、体积、渲染性能
5.1 地图偏移几百米:坐标系不匹配
现象:GeoJSON 叠加到高德或百度底图上,边界整体偏移。原因:GeoJSON 是 WGS84,国内底图是 GCJ-02 或 BD-09。解决:用coordtransform或gcoord库转换坐标,或者换用 WGS84 底图。注意转换只针对国内区域,全球数据转换要按区域判断。
5.2 填色不生效:属性字段名对不上
现象:ECharts 地图渲染出来了,但data里的国家没有颜色。原因:series.data[].name和 GeoJSONproperties里的字段值不一致,比如数据里是 “United States”,GeoJSON 里是 “United States of America”。解决:先console.log(worldGeoJson.features[0].properties)看字段名和值,再做映射。常见做法是建一个名称映射表。
5.3 浏览器卡死:高精度数据直接渲染
现象:加载 1:10m 精度的全球数据后,页面滚动卡顿,缩放延迟。原因:坐标点太多,SVG 或 Canvas 渲染压力大。解决:用 mapshaper 简化到 1:50m 或 1:110m,或者用 TopoJSON 减少冗余。如果必须用高精度,考虑用 Canvas 渲染替代 SVG,或者做矢量瓦片。
5.4 ArcGIS 打开报错:JSON 格式不标准
现象:ArcGIS 提示“无法解析 JSON”或“不支持的类型”。原因:有些 GeoJSON 文件顶层不是FeatureCollection,而是单个Feature或Geometry。解决:用文本编辑器确认顶层type字段,如果是Feature就手动包一层FeatureCollection。另外,ArcGIS 对properties里的嵌套对象支持不好,尽量扁平化。
5.5 文件体积过大:没做压缩和按需加载
现象:项目打包后体积暴涨,首屏加载慢。原因:把全球高精度 GeoJSON 直接 import 进前端代码。解决:按需加载,比如用户点击某个国家再请求对应文件;或者用fetch动态获取,不打包进 bundle。常见做法是把 GeoJSON 放在 CDN 或静态目录,用 URL 请求。
6. 进阶技巧:用 TopoJSON 压缩体积并保持边界共享
TopoJSON 的核心优势是弧段共享。相邻国家的边界在 GeoJSON 里是两份坐标,在 TopoJSON 里只存一份,通过索引引用。全球数据转 TopoJSON 后体积通常能减少 60% 到 80%。转换用topojson-server和topojson-client两个 npm 包。
// 服务端或构建脚本中转换 const topojson = require('topojson-server'); const fs = require('fs'); const worldGeoJson = JSON.parse(fs.readFileSync('world.geojson', 'utf-8')); // 转换为 TopoJSON,指定要保留的属性 const topology = topojson.topology({ world: worldGeoJson }); fs.writeFileSync('world.topojson', JSON.stringify(topology));前端加载时用topojson-client还原成 GeoJSON 再交给 ECharts 或 D3。
import * as topojson from 'topojson-client'; import topology from './data/world.topojson'; // 还原成 GeoJSON FeatureCollection const worldGeoJson = topojson.feature(topology, topology.objects.world); // 后续和普通 GeoJSON 一样使用 echarts.registerMap('world', worldGeoJson);参数说明:topology函数的第一个参数是一个对象,键名world是自定义的,还原时要用topology.objects.world对应。topojson.feature返回标准 GeoJSON。注意 TopoJSON 的坐标是量化的,默认精度可能损失细节,可以在转换时用-q参数控制量化位数,或者用topojson-simplify做进一步简化。
验证方法:转换前后用JSON.stringify对比文件大小,用 QGIS 打开确认边界没有明显变形。我一般会在转换后随机抽几个国家放大看边界,确认没有出现锯齿或断裂。从那以后我每次处理全球数据都强制走一遍“GeoJSON 调试 → TopoJSON 上线”的流程,省得后期被体积问题追着跑。希望帮到你。
本文还有配套的精品资源,点击获取