资讯动态

世界地图GeoJSON资源:开箱即用的国家边界数据与Web可视化实践

发布时间:2026/10/16 10:48:39 来源:尧图企业网站定制
简介这份资源整理了世界地图与主要国家的 GeoJSON 数据面向从事数据可视化、Web 地图开发的前端工程师与 GIS 初学者解决绘制世界或单国地图时缺少现成边界数据的问题。压缩包共 25 个文件以 23 个 json 为主涵盖 world.json 及德国、英国、瑞士、日本、俄罗斯、澳大利亚、美国、法国、巴西、韩国、新加坡等主要国家另有 2 个 mht 文件记录 D3.js 地图学习资料整体约 11.31MB。由于原始文件体积偏大作者建议下载后到 mapshaper.org 按需简化以适配网页加载性能。目前已有 6260 人学习下载说明该数据在可视化社区中具备一定认可度。读者可直接获得开箱即用的世界及多国边界数据省去自行采集与格式转换的环节配合 D3.js 等库即可快速完成地图渲染、区域着色与交互探索也便于按国家拆分做专题分析。1. 世界地图 GeoJSON 资源从一份 JSON 到能跑的地图做数据可视化或者 GIS 相关开发的人迟早会碰到一个需求我需要一份干净、完整、能直接用的世界地图和主要国家的边界数据。网上搜一圈要么是 shapefile 需要额外工具转换要么是 TopoJSON 还得引额外依赖要么就是数据缺胳膊少腿——某个国家的边界线断了或者属性表里连国家名都没有。这份「世界地图和主要国家的 JSON (GeoJSON)」资源解决的就是这个最前置、也最容易被低估的问题给你一份开箱即用的 GeoJSON 文件直接丢进 ECharts、Leaflet、Mapbox、D3 或者 Python 的 GeoPandas 里就能渲染。它适合谁做前端地图可视化的、写数据大屏的、搞地理数据分析的以及任何需要国家边界几何数据但不想从 Natural Earth 原始 shapefile 开始折腾的人。2. GeoJSON 格式拆解为什么它比 Shapefile 更适合 Web 场景2.1 GeoJSON 的核心结构FeatureCollection 与 GeometryGeoJSON 本质上是 JSON 格式的地理空间数据交换标准RFC 7946。一份世界地图 GeoJSON 的顶层通常是一个FeatureCollection里面装着一堆Feature每个Feature包含geometry几何形状和properties属性信息。几何类型常见的有Polygon单个国家主体和MultiPolygon岛屿多的国家比如日本、菲律宾、印尼。属性里一般会有国家名称、ISO 代码、行政区划类型等字段。为什么 Web 场景优先选 GeoJSON 而不是 ShapefileShapefile 是一套多文件格式.shp/.shx/.dbf/.prj浏览器端没法直接解析必须后端转成 GeoJSON 或者用 shapefile.js 这类库在前端硬解性能和兼容性都不理想。GeoJSON 就是纯文本 JSONfetch回来JSON.parse就能用和 JavaScript 生态无缝衔接。TopoJSON 虽然体积更小通过拓扑编码压缩共享边界但需要额外引入 topojson-client 做解码多一层依赖就多一个翻车点。2.2 这份资源里有什么文件组织与字段说明根据标题和常见组织方式这份资源通常包含两类文件一份全球尺度的世界地图 GeoJSON以及若干主要国家的单独 GeoJSON 文件。世界地图文件覆盖全球国家边界国家文件则把单个国家的几何数据拆出来方便按需加载。文件类型典型命名几何类型属性字段常见适用场景世界地图world.geo.json / world.jsonMultiPolygon 为主name, iso_a2, iso_a3, continent全球数据大屏、 choropleth 地图单国地图china.json / usa.jsonPolygon / MultiPolygonname, adcode, center国家内部区域着色、钻取交互属性字段的具体名称取决于数据来源。常见的有name英文名、name_zh中文名部分资源会带、iso_a2两位国家代码、iso_a3三位代码。如果你要做中文地图先确认properties里有没有中文名字段没有的话需要自己维护一张 ISO 代码到中文名的映射表。注意不同来源的 GeoJSON 属性字段命名不统一拿到文件后第一件事是console.log或print看一个 Feature 的 properties 结构别假设字段名。2.3 用 Python 快速验证数据完整性拿到 GeoJSON 文件后别急着往项目里塞。先用 Python 做一轮体检确认几何有效、属性齐全、坐标范围正常。import json # 加载 GeoJSON 文件 with open(world.geo.json, r, encodingutf-8) as f: data json.load(f) # 检查顶层结构 print(类型:, data.get(type)) # 应为 FeatureCollection features data.get(features, []) print(要素数量:, len(features)) # 检查第一个要素的属性字段 first features[0] print(属性字段:, list(first[properties].keys())) print(几何类型:, first[geometry][type]) # 统计几何类型分布 from collections import Counter geom_types Counter(f[geometry][type] for f in features) print(几何类型分布:, dict(geom_types)) # 检查坐标范围是否合理经度 -180~180纬度 -90~90 def check_bounds(coords): if isinstance(coords[0], (int, float)): lon, lat coords[0], coords[1] return -180 lon 180 and -90 lat 90 return all(check_bounds(c) for c in coords) bad [f[properties].get(name, unknown) for f in features if not check_bounds(f[geometry][coordinates])] print(坐标异常的国家:, bad if bad else 无)这段脚本做了四件事确认顶层是FeatureCollection、统计要素数量、查看属性字段名、检查坐标是否在合法范围内。如果bad列表非空说明有国家的坐标数据有问题可能是投影没转回 WGS84 经纬度需要重新处理。check_bounds递归遍历嵌套坐标数组兼容 Polygon 和 MultiPolygon 两种结构。3. 在 Web 前端落地ECharts 与 Leaflet 两条路线3.1 ECharts 注册地图三行代码搞定ECharts 是国内数据大屏最常用的图表库它内置了地图组件但需要你先注册 GeoJSON 数据。import * as echarts from echarts; // 加载 GeoJSON 数据 fetch(/data/world.geo.json) .then(res res.json()) .then(geoJson { // 注册地图world 是自定义地图名 echarts.registerMap(world, geoJson); const chart echarts.init(document.getElementById(map)); chart.setOption({ series: [{ type: map, map: world, // 对应 registerMap 的名字 roam: true, // 允许缩放和拖拽 label: { show: false }, // 国家名太多默认关掉 emphasis: { // 鼠标悬浮高亮 label: { show: true }, itemStyle: { areaColor: #ffd700 } }, data: [] // 你的业务数据格式 [{name: China, value: 100}] }] }); });关键点在echarts.registerMap(world, geoJson)这一行。注册之后series.map的值必须和注册名一致。roam: true开启缩放拖拽大屏上一般会开。data数组里的name字段必须和 GeoJSON 里properties.name的值完全匹配否则数据映射不上——这是最常见的翻车点。如果 GeoJSON 里用的是英文名而你的数据是中文名要么改数据要么在 GeoJSON 里加一个中文名字段。3.2 Leaflet 加载 GeoJSONL.geoJSON 的样式与交互Leaflet 是另一个主流选择轻量、插件生态好。加载 GeoJSON 用L.geoJSON方法。import L from leaflet; const map L.map(map).setView([20, 0], 2); // 纬度、经度、缩放级别 // 底图用 OpenStreetMap L.tileLayer(https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png, { attribution: © OpenStreetMap contributors }).addTo(map); // 加载 GeoJSON 并设置样式 fetch(/data/world.geo.json) .then(res res.json()) .then(geoJson { L.geoJSON(geoJson, { style: function(feature) { return { color: #3388ff, // 边界线颜色 weight: 1, // 线宽 fillColor: #3388ff, // 填充色 fillOpacity: 0.1 // 填充透明度 }; }, onEachFeature: function(feature, layer) { // 绑定点击弹窗 if (feature.properties feature.properties.name) { layer.bindPopup(feature.properties.name); } // 鼠标悬浮高亮 layer.on(mouseover, function() { this.setStyle({ fillOpacity: 0.4 }); }); layer.on(mouseout, function() { this.setStyle({ fillOpacity: 0.1 }); }); } }).addTo(map); });style函数对每个 Feature 调用一次返回样式对象。onEachFeature是绑定交互的入口bindPopup做点击弹窗mouseover/mouseout做悬浮效果。Leaflet 的坐标系默认是 WGS84 经纬度EPSG:4326GeoJSON 标准也是 WGS84所以不需要额外投影转换。如果你的 GeoJSON 用的是 Web MercatorEPSG:3857Leaflet 也能显示但坐标值会很大需要确认数据源。3.3 按需加载单国数据减少首屏体积世界地图 GeoJSON 动辄几 MB如果用户只关心某个国家全量加载就是浪费。常见做法是首屏只加载世界地图的低精度版本用户点击某个国家后再异步加载该国的高精度 GeoJSON。// 点击国家后加载详细数据 function loadCountryDetail(isoCode) { const url /data/countries/${isoCode.toLowerCase()}.geo.json; fetch(url) .then(res { if (!res.ok) throw new Error(加载 ${isoCode} 失败); return res.json(); }) .then(detail { // 清除旧图层加载新图层 if (window.currentDetailLayer) { map.removeLayer(window.currentDetailLayer); } window.currentDetailLayer L.geoJSON(detail, { style: { color: #e74c3c, weight: 2 } }).addTo(map); }) .catch(err console.error(err)); }isoCode用两位国家代码如cn、us、jp文件名统一小写。加载前先移除旧图层避免叠加。错误处理不能省——文件不存在时fetch不会抛异常但res.ok为false需要手动判断。4. 避坑与排查GeoJSON 使用中的五个血泪教训4.1 地图渲染空白坐标顺序搞反了现象地图区域一片空白控制台无报错或者地图跑到南极去了。原因GeoJSON 标准规定坐标顺序是[经度, 纬度]但有些数据源尤其是从某些 GIS 工具导出的会写成[纬度, 经度]。顺序反了之后经度值当纬度用整个地图就飞到南极或者形状完全错乱。解决写一个检测脚本遍历所有坐标点如果发现大量点的第一个值在 -90 到 90 之间而第二个值超出这个范围基本可以判定顺序反了。修复方法是递归交换每个坐标对的顺序。def swap_coords(coords): if isinstance(coords[0], (int, float)): return [coords[1], coords[0]] # 交换经纬度 return [swap_coords(c) for c in coords] for feature in data[features]: feature[geometry][coordinates] swap_coords(feature[geometry][coordinates])4.2 数据映射不上name 字段不匹配现象ECharts 地图渲染出来了但data里的数值没有着色所有国家都是默认颜色。原因series.data里的name值和 GeoJSONproperties.name不一致。常见差异包括大小写不同Chinavschina、中英文不同Chinavs中国、有空格United StatesvsUnitedStates。解决先打印 GeoJSON 里所有properties.name的值再打印你数据里的 name 值做一次 diff。统一方案是维护一张映射表或者直接在 GeoJSON 里加一个和业务数据一致的字段。4.3 文件太大导致加载慢简化几何精度现象世界地图 GeoJSON 文件 10MB首屏加载要好几秒移动端直接卡死。原因原始边界数据精度太高每个国家的轮廓有几千个坐标点全球加起来就是海量数据。解决用地图简化算法如 Douglas-Peucker降低精度。Python 的shapely库可以做简化或者用mapshaper命令行工具。# 用 mapshaper 简化保留 10% 的坐标点 mapshaper world.geo.json -simplify 10% -o formatgeojson world-simplified.geo.json简化比例根据场景定大屏展示 5%-10% 足够需要精确边界如国土规划就别简化。4.4 岛屿国家显示不全MultiPolygon 处理遗漏现象日本、菲律宾、印尼等岛国只显示了主岛周围小岛不见了。原因这些国家的几何类型是MultiPolygon包含多个多边形。如果代码里只取了coordinates[0]就只渲染了第一个多边形。解决确保渲染库支持MultiPolygon。ECharts 和 Leaflet 都原生支持问题通常出在自己写的解析代码里。检查是否有coordinates[0]这种硬编码索引。4.5 中文显示乱码编码问题现象国家名显示为乱码或问号。原因GeoJSON 文件保存时用了非 UTF-8 编码或者 HTTP 响应头没有正确设置Content-Type: application/json; charsetutf-8。解决用file命令检查文件编码统一转成 UTF-8。服务端返回 JSON 时设置正确的 Content-Type。前端fetch默认按 UTF-8 解析一般不需要额外处理。5. 进阶技巧用 GeoPandas 做空间分析与数据校验5.1 GeoPandas 读取与拓扑检查如果你不只是渲染还要做空间分析比如计算国家面积、判断点是否在境内Python 的 GeoPandas 是首选工具。import geopandas as gpd # 读取 GeoJSON gdf gpd.read_file(world.geo.json) # 查看基本信息 print(gdf.crs) # 坐标参考系应为 EPSG:4326 print(gdf.shape) # 行数和列数 print(gdf.columns.tolist()) # 检查几何有效性 invalid gdf[~gdf.geometry.is_valid] print(f无效几何: {len(invalid)} 个) if len(invalid) 0: print(invalid[[name]].head()) # 修复无效几何 gdf[geometry] gdf.geometry.buffer(0) # buffer(0) 是常用的修复手段gdf.crs告诉你坐标参考系如果是None说明文件里没有 CRS 信息需要手动设置gdf.set_crs(EPSG:4326, inplaceTrue)。is_valid检查几何是否有自相交、重复点等问题buffer(0)是最常用的修复方法虽然不保证完美但能解决大部分问题。5.2 计算面积与中心点投影转换不能省直接用 WGS84 经纬度算面积是不准的因为经纬度是角度单位不是长度单位。需要先投影到等面积投影。# 投影到 Mollweide 等面积投影 gdf_projected gdf.to_crs(ESRI:54009) # 计算面积平方公里 gdf[area_km2] gdf_projected.geometry.area / 1e6 # 计算每个国家的中心点用于标注 gdf[centroid] gdf.geometry.representative_point() gdf[centroid_lon] gdf[centroid].x gdf[centroid_lat] gdf[centroid].y # 输出面积最大的十个国家 print(gdf.nlargest(10, area_km2)[[name, area_km2]])to_crs(ESRI:54009)转到 Mollweide 投影这是一个等面积投影适合做面积计算。representative_point()比centroid更安全因为centroid可能落在多边形外部比如月牙形国家representative_point保证点在多边形内部。5.3 导出为其他格式Shapefile 与 GeoPackage有时候下游系统需要 Shapefile 或 GeoPackageGeoPandas 一行代码就能转。# 导出为 Shapefile注意字段名会被截断到 10 个字符 gdf.to_file(world.shp, encodingutf-8) # 导出为 GeoPackage推荐支持长字段名和 UTF-8 gdf.to_file(world.gpkg, driverGPKG)Shapefile 的字段名限制是 10 个字符area_km2会被截断成area_km2刚好 8 个字符没问题但更长的字段名就会丢信息。GeoPackage 没有这个限制是更现代的替代方案。5.4 一个我常用的校验习惯每次拿到新的 GeoJSON 文件我都会跑一遍这个检查清单顶层类型是不是FeatureCollection、要素数量是否合理、properties里有没有可用的名称字段、坐标范围是否在合法区间、几何是否有效、有没有重复的name值。这套流程帮我挡掉过好几次数据源本身就有问题的坑——有一次某个国家的边界数据里混入了另一国的飞地导致面积计算直接翻倍。从那以后我每次拿到新数据都强制走一遍这个校验流程再急也不跳过。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑