恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
世界国家GeoJSON大全:从边界数据到地图绘制的完整实战指南
首页
资讯中心
/
世界国家GeoJSON大全:从边界数据到地图绘制的完整实战指南
世界国家GeoJSON大全:从边界数据到地图绘制的完整实战指南
发布时间:2026/10/11 15:12:58
简介世界国家geojson大全是一套面向地图开发与GIS学习者的全球边界数据包为世界各国和地区提供可直接使用的geojson多边形数据源自Natural Earth特别适合在Web地图、数据可视化或GIS软件中快速绘制小比例尺的精致地图。压缩包仅1.87MB共含3446个文件其中3442个json为各级地理边界数据另有2个md说明文档和1个Unlicense许可文件便于了解数据来源与开放使用。已覆盖全球主要国家及众多细分区域文件按国名或区域名清晰命名可按需加载单国或局部地图既能用于前端D3、Leaflet等可视化也可支撑桌面GIS或地理分析项目。数据包已有3058人浏览学习对于需要快速获取全球地图轮廓、搭建地图展示或开展空间分析的开发者来说是一份实用且轻量的基础数据包。1. 世界国家 GeoJSON 大全是什么不止是一堆 json 文件做地图可视化、行政区下钻、区域业务分析时最耗时间的往往不是画图代码而是手里没有一份干净可用的边界数据。世界国家 GeoJSON 大全本质是把全球各国家和地区的行政区划边界整理成 JSON 格式的汇总数据包解决“某个区域在哪、边界长什么样、对应什么属性”这三件事。它适合前端工程师、数据分析师、以及刚接触 GIS 的新手。很多人拿到数据包后直接开画结果边界错位、属性为空、坐标数值对不上。这套流程从验收到绘图、裁剪和避坑讲透先强调一个反直觉的事实再权威的数据包也不等于能直接上线的地图底图。2. GeoJSON 的结构与选型理由为什么前后端都认它2.1 三个必懂概念FeatureCollection、Feature 与 GeometryGeoJSON 不是某公司私有的封闭格式而是一套由地理信息社区共同维护的开放编码规范。整套世界国家数据在文件里呈现为一个 FeatureCollection 对象可以把它理解为一张“包含很多行的表格”每一行是一个 Featuregeometry 列画边界properties 列写属性。geometry 的取值类型中最常见的两种是 Polygon 和 MultiPolygon。单个国家往往不止一块领土岛屿国家一块主岛加若干离岛就自然落在 MultiPolygon 中单一连续陆地的国家多数是 Polygon。判断一个数据包是否专业先看它对 MultiPolygon 的处理是否规范——坐标数组嵌套在合理层级上一个环闭合不留多余的洞。我遇到过不少开发者最大的疑问是“为什么我平铺的经纬度数组不能直接用”。这里的关键在于嵌套层级。以 MultiPolygon 为例{ type: FeatureCollection, features: [ { type: Feature, properties: { name: 示例国家A, iso2: XX }, geometry: { type: MultiPolygon, coordinates: [ [[ [100.0, 30.0], [101.0, 31.0], [102.0, 30.5], [100.0, 30.0] ]] ] } } ] }这里的层级顺序是MultiPolygon → Polygon → 外环 → 坐标点。如果剥错一层例如把外环的数组直接当坐标点传渲染库就会把一连串经纬度按顺序连成一条乱线。properties 的字段名也不统一有的叫 name有的叫 admin有的叫 NAME_EN。所以任何数据包到手必须先用脚本读取一遍字段列表再开始画图。这套动作我把它叫做“体检”下一个节具体演示。为什么选 GeoJSON 而不是传统的 Shapefile两点单体文件。Shapefile 至少由 .shp、.shx、.dbf 三个文件组成缺一个就打不开还要配套 PRJ 定义坐标GeoJSON 一个文件即可完整表达。解析成本低。JSON 的原生结构让 JavaScript 直接在浏览器里取值不用加载额外的二进制转码库Python 端用 geopandas 一行即可读入。2.2 体检步骤用 Python 验证这份世界数据能不能直接用先安装依赖。常见做法是 conda 或 pip 安装 geopandas然后按下面流程操作。import zipfile import geopandas as gpd with zipfile.ZipFile(世界国家geojson大全_地图数据.zip, r) as z: z.extractall(./geo_data) world gpd.read_file(./geo_data/countries.geojson) print(总行数, len(world)) print(字段, world.columns.to_list()) print(坐标系, world.crs) print(几何类型, world.geom_type.unique())逻辑说明geopandas 的 read_file 会自动识别 GeoJSON 里的 FeatureCollection 结构并转换成 GeoDataFrame等价于一张表格加一列特殊几何列。命令运行后四个打印值是我们判断数据可用性的四个关键信号总行数。完整的世界国家边界数据通常有 180 行以上太少则可能是精简版或内容不全。字段列表。至少应该有名称字段和 ISO 代码字段如果只有 geometry 没有 properties后续做下钻交互会很麻烦。坐标系。GeoJSON 规范要求用 WGS84 经纬度EPSG:4326。如果打印出来是 None说明原数据没有显式写入坐标系统不能直接进绘制流程。几何类型。正常情况应同时出现 Polygon 和 MultiPolygon。如果只有一种并且声称是完整数据那要么被过滤过要么数据源本身不完整。若坐标系为空补一手if world.crs is None: world world.set_crs(EPSG:4326) print(world.crs) # 现在应显示 EPSG:4326还有个坑坐标范围看起来正常经度 -180~180纬度 -90~90坐标是经纬度但 crs 是 None这种情况设置 4326 即可如果坐标是百万级那它是投影坐标必须先转投影再落回经纬度。拿地图数据后先跑这三个验证再画图大约只需要两分钟能提前屏蔽后续一半以上的混乱。3. 用 Python 画一张世界地图最小可复现代码3.1 最小绘图脚本从读文件到保存 PNG有了 GeoJSON 文件后后续步骤很直接。把经纬度画到画布上就是绘图脚本要做的事情。import geopandas as gpd import matplotlib.pyplot as plt world gpd.read_file(./geo_data/countries.geojson) fig, ax plt.subplots(figsize(16, 8)) world.plot( axax, facecolor#f2f2f2, # 每个国家内部填充色 edgecolor#999999, # 国界轮廓色 linewidth0.3 # 轮廓线宽 ) ax.set_xlim(-180, 180) # 经度范围 ax.set_ylim(-60, 85) # 纬度范围 ax.axis(off) # 关闭坐标轴刻度 plt.tight_layout() plt.savefig(world_map.png, dpi150)这段代码的逻辑read_file 是读取步骤和体检时一样。plot 时 GeoDataFrame 会把每个 Feature 的 geometry 按画布坐标画出来facecolor 填充内部edgecolor 描国界。set_xlim/set_ylim 决定看地球的哪一块窗口如果不设置范围自动适应往往会把角落的空白一起画进图里。tight_layout 压缩空白让画布利用率高。savefig 保存 PNG 时 dpi 控制像素密度一般 150 足够。补充一个易错点如果看到图片右上角有几个小点挤在一角多半是没有设置坐标范围数据里的离岛坐标把图的 xy 范围撑大了。用上面固定范围就能规避。3.2 必调的 3 个参数坐标范围、线宽、颜色这三个是最容易做得“自以为能用”又效果很差的参数。坐标范围。全览世界常用 [-180, 180, -60, 85]右边数值决定垂直覆盖纬度从 -60 到 85 是不少可视化惯用裁切即不绘制南北极附近区域。看特定区域时改范围即可例如看欧洲大陆可以 set_xlim(-30, 50)、set_ylim(35, 70)。注意 matplotlib 的 xlim/ylim 里传的是“经度在前纬度在后”。线宽。线宽单位是 point。全球图用 0.3 比较合适如果只画某个国家线条可到 1.0 以上。线宽跟绘图画面大小成正比用大 figsize 时线宽也要相应减少否则线条粗得像描边。颜色。填充色太深国界细节会被吞掉宜用浅灰国界色太浅区域之间就会糊成一片。这些不是玄学而是视觉场景的实际取舍。需要突出某个国家时把目标区域 fillColor 改成高饱和色别的国家保持浅灰能立刻做出重点提示。3.3 前端路线用 Leaflet 加载同一份 GeoJSONPython 绘图适合出静态图但交互式地图通常还是浏览器主导。常见做法是用 Leaflet 或 OpenLayers 加载同样的 GeoJSON。下面是一个最小页面重点在 fetch 和 L.geoJSON 两步。!DOCTYPE html html head meta charsetutf-8 title世界国家地图/title style html, body, #map { height: 100%; margin: 0; } /style link relstylesheet href./lib/leaflet/leaflet.css / script src./lib/leaflet/leaflet.js/script /head body div idmap/div script const map L.map(map).setView([20, 0], 2); // 底图瓦片地址换成你自己环境里能访问的 L.tileLayer(https://your-tile-server.local/{z}/{x}/{y}.png, { maxZoom: 10 }).addTo(map); fetch(./countries.geojson) .then(res res.json()) .then(data { L.geoJSON(data, { style: { color: #666, weight: 0.5, fillColor: #e8e8e8, fillOpacity: 0.8 } }).addTo(map); }); /script /body /html拿不到合适瓦片底图时只需少传 L.tileLayer 的 URL然后把 #map 的背景色设浅色地图就变成纯色底加 GeoJSON 边界。这样就不会在演示机上因为网络问题黑屏。Leaflet 里 L.geoJSON 会解析 FeatureCollection默认每个 Feature 画成一个图层style 对象统一套用。想实现悬停高亮可以看后面的进阶写法按属性返回样式。4. 把下载包转成自己的地图包裁剪、抽稀、换格式4.1 按国家裁剪只保留需要的区域拿到全世界数据后一个实际场景是“只要几个区域做分析”。在源头剪比在浏览器里加载全量后隐藏要快得多。import geopandas as gpd world gpd.read_file(./geo_data/countries.geojson) target [示例国家A, 示例国家B] subset world[world[name].isin(target)].copy() subset.to_file(focus.geojson, driverGeoJSON, encodingutf-8) print(len(subset), 个区域已导出)逻辑解释world[name] 是前面体检看到的国家名称字段如果体检时字段叫 admin这里就要相应替换。isin 是 pandas 的布尔筛选括号里填你想保留的国家名。copy() 是必须的习惯pandas 切片的子集在修改时可能触发警告先 copy 可以把隐患掐在源头。to_file 的 encoding 指定 UTF-8避免中文属性乱码。输出文件只有目标数据体积和加载耗时都明显下降。4.2 坐标精度取舍保留多少位小数才不背锅全球数据包的坐标精度通常很高但 GeoJSON 是文本格式坐标每多一位小数文件体积就大一些。一个坐标点 0.0000001 度大约 1 厘米的精度处理大范围全球地图这种精度没有意义。经验参考精度意义适合场景3 位小数约 100 米全球缩放、示意图5 位小数约 1 米市级或省级底图6 位小数约 0.1 米高精测绘或局部放大处理方式很直接import json def round_coords(obj, digits4): if isinstance(obj, list): if obj and isinstance(obj[0], (int, float)): return [round(obj[0], digits), round(obj[1], digits)] return [round_coords(x, digits) for x in obj] return obj with open(countries.geojson, encodingutf-8) as f: gj json.load(f) for feat in gj[features]: feat[geometry][coordinates] round_coords(feat[geometry][coordinates], 4) with open(countries_rounded.geojson, w, encodingutf-8) as f: json.dump(gj, f, ensure_asciiFalse)递归思路如果当前对象是列表先看第一个元素是不是数若是数就把它当作坐标点截断否则继续向下递归。几何类型为 Polygon 或 MultiPolygon 时都能正确套用。round 的 digits 对应上表的小数位数海外小岛很多的数据选 4 位可以兼顾体积和视觉。4.3 体积优化simplify 抽稀与 TopoJSON 的取舍坐标截断只能压小位的字节数对控制“点密度”作用不大。对点很多的边界做抽稀常用 shapely 的 simplify。tolerance 0.01 # 在此范围内的相邻点会被合并单位是度 world[simple_geometry] world.geometry.simplify( tolerance, preserve_topologyTrue ) world world.set_geometry(simple_geometry) world.to_file(countries_simple.geojson, driverGeoJSON, encodingutf-8)simplify 按抽稀算法去掉离近似线段距离不超过 tolerance 的顶点。tolerance 以“度”为单位0.01 大约对应 1 公里做全球图时边界形状依然可辨认。如果 tolerance 超过 0.05某些小岛会缩成很小或消失需要肉眼复查。preserve_topologyTrue 很重要能防止简化后相邻国家的多边形裂开或互相穿插。TopoJSON 是更彻底的拓扑压缩相邻国家共享同一条边界只保存一次。GeoJSON 里每个国家独立记录共享国界存两遍TopoJSON 把这条弧只存一遍再通过索引引用体积通常再减一半甚至更多。代价是前端解析库要额外引入 topojson-client。别把 TopoJSON 当成万能药后端做空间运算时geopandas 直接读 GeoJSON 顺滑TopoJSON 支持有限。选择格式看场景给浏览器整屏加载就用 TopoJSON给空间分析用 GeoJSON。压缩包里的原始 GeoJSON 建议保留一份作为源头所有精简版本都从这个源文件派生。5. 世界地图数据实战避坑5 条典型的排查记录5.1 现象国界错位图形整体偏移现象渲染出来的边界和底图对不上有时整个图形偏移几十上百公里或者相邻国家边缘出现明显间隙和重影。原因一是坐标系不一致。GeoJSON 承诺的是 WGS84 经纬度但有的数据是投影坐标或保存错了坐标系加载后坐标到达数百万量级。二是数据源对坐标做了偏移处理比例对了但对位不上这种情况人工很难修复。解决用坐标范围快速判读出问题。world gpd.read_file(countries.geojson) if world.crs is None: world world.set_crs(EPSG:4326) # 如果坐标值很大且 crs 显示 4326说明可能存错了坐标系 if world.total_bounds.max() 1000: print(坐标疑似投影坐标需转回经纬度) world world.set_crs(EPSG:3857).to_crs(EPSG:4326)total_bounds 返回四个值 minx、miny、maxx、maxy。全球经纬度范围的最大值不会超过 180如果最大值大于 1000几乎可以肯定是投影坐标。对生产级地图偏移数据换源比手动校偏更靠谱。5.2 现象画出来的图只有一个点或一条线现象加载后地图区域只见一个点、一条斜线整个底图基本是空的。原因JSON 结构层级出错或几何类型被破坏。比如 MultiPolygon 的坐标在外层过滤时被简化成一维数组渲染库把它当成一个点坐标环没有闭合则可能被当成线。排查print(world.geom_type.unique()) # 只有 Point 或 LineString 就说明结构损坏 world world[world.geometry.geom_type.isin([Polygon, MultiPolygon])].copy() world world[world.geometry.is_valid]如果 valid 过滤后剩下很少行说明原文件大面积损坏。试着用 shapely 修复from shapely.validation import make_valid world[geometry] world.geometry.apply(lambda g: make_valid(g))修复后的几何类型可能变成 GeometryCollection它们暂时不是标准 Polygon 或 MultiPolygon前端渲染时仍可能出问题转换后要再验证一遍。对“环没闭合”的情况buffer(0) 常能救回来world[geometry] world.geometry.buffer(0)buffer(0) 会把损坏面重新整理成合法面顺手把自相交问题修掉代价是处理耗时随点数增加适合中等数据量。5.3 现象浏览器加载白屏数据一多就卡死现象打开页面后一直白屏拖动时掉帧最后标签页无响应。多数不是渲染库的锅而是 GeoJSON 数据量太大。优化分层第一层精简属性只保留 name 和 iso第二层坐标降位到 4 位第三层 simplify 抽稀把点量压下来第四层如果还大改用 TopoJSON或拆成多个文件按需加载。在 Leaflet 里降低交互负担可以这样L.geoJSON(data, { style: { color: #888, weight: 0.3, fillColor: #eee, fillOpacity: 0.5 }, interactive: true }).addTo(map);大数据场景的常用路数是分级加载先放一个粗糙版全球数据下钻到某个国家时再 fetch 那个国家的精细文件。一次全载几 MB 数据再好的浏览器也会卡。5.4 现象相邻国家边界重叠、互相穿透现象缩放时两个相邻国家填充色重叠鼠标或点选时会把两个国家都点亮或者国界之间有明显的缝隙。原因多个国家从不同来源拼接而来每条国界线在相邻文件里各画了一道两个面之间自然出现重叠或缝隙。处理方案优先选择一份统一处理过边界的全球文件而不是自己拼几十个国家文件。次优做法是绘制时不把每个国家单独渲染先聚合为一层做全量填充再在高亮层单独画需要突出的国家让重叠视觉影响降到最低。国界线设置细线color 用 #666、weight 用 0.3填透明度降到 0.5 以下即使两图重叠视觉上也不显脏。重叠问题想彻底修复需要做拓扑对齐这不是普通应用开发者日常值得维护的范围换源更现实。5.5 现象解压后文件名乱码或属性表中文乱码现象解压 zip 时文件名变成看不懂的符号geopandas 读取后 name 字段中文变乱码。原因文件名字符集不一致。旧压缩包工具在 zip 里保存文件名用的是本地编码现在大部分环境期望 UTF-8解压时两边对不上就成了乱码。属性字段乱码则是导出时没有指定 UTF-8或读取时用了错误编码。代码侧处理world gpd.read_file(countries.geojson, encodingutf-8) # 如果源数据本身是 GBK 编码把 encoding 换成 gbk文件名乱码在 Windows 上常用方案是用支持编码选择的解压工具手动解压并在弹窗里选“以 UTF-8 文件名读取”。一句话拿到数据包先记录文件编码是 UTF-8 还是 GBK。生产环境下不要假定编码读取前先 print 看一眼。6. 进阶技巧用属性字段做区域高亮与多维渲染6.1 一张图突出热点function 样式按属性返回Leaflet 的 L.geoJSON 第二参数里的 style 可以是一个函数。function highLightStyle(feature) { const name feature.properties.name; if (name 示例国家A) { return { color: #d73027, weight: 1.5, fillColor: #fdae61 }; } if (name 示例国家B) { return { color: #313695, weight: 1.5, fillColor: #74add1 }; } return { color: #ccc, weight: 0.3, fillColor: #eee, fillOpacity: 0.8 }; } L.geoJSON(data, { style: highLightStyle }).addTo(map);这个样式函数每次绘制都会调用性能开销极小。把示例国家名替换成你自己的属性值即可。如果想把数值型属性做分档着色在函数里对属性做分段判断、返回不同颜色就能做出带“热力”风格的国家边界。6.2 两个踩过坑后养成的数据管理习惯第一个习惯任何地图数据下载后立刻在项目 data 目录里写一份简要说明记下坐标系、精度、来源和原始文件名。这样换了环境或半年后维护不靠记忆。第二个习惯保留一份全量原版再派生一份“渲染版”。渲染版是过滤属性、坐标降位、抽稀过的版本只给前端使用分析场景一律用原版避免因为显示精度影响统计结果。之前我在一个模拟项目 X 里从渲染版直接做空间相交统计抽稀后的边界面积偏了不少统计结果一路错到汇报阶段整个项目白折腾了两天。后来我养成习惯原版不动任何加工都在副本上进行渲染版和分析版分开目录放。这套习惯看着简单但能把地图可视化项目里最难追的问题挡在门外。希望帮到你。本文还有配套的精品资源点击获取