广东省行政区划shp文件处理:从边界底图到轻量GeoJSON的完整流程

发布时间:2026/10/11 20:18:31
广东省行政区划shp文件处理:从边界底图到轻量GeoJSON的完整流程 简介广东省行政区划SHP文件是一份面向GIS学习者和城市规划、区域分析从业者的矢量边界数据包对应广东省级及地市级行政区域几何信息与属性记录可直接用于地图可视化、空间查询与基础制图。压缩包内含17个文件约17.55MB主要文件类型包括.shp几何数据、.dbf属性数据、.shx索引、.prj投影参数以及辅助的.adf与.xml元数据等方便在ArcGIS、QGIS等平台中加载使用。已有5625人浏览学习。这份数据包适合用来熟悉Shapefile的文件构成与坐标投影设置也可作为课堂练习或项目前期验证的底图数据借助GDAL/OGR或相关GIS工具还能进一步完成行政边界合并、要素筛选、区域统计等空间分析帮助读者快速上手处理同类矢量数据。1. 广东省行政区划shp文件一切地图项目绕不开的基础底图“广东省行政区划shp文件”这句话在多数落地项目里不是给你一份文件就结束而是整套后续工作的起点。它本质上是把广东从省级到乡镇街道的行政边界用 ESRI Shapefile 这种矢量格式存储成一套文件地图可视化、区域统计、业务指标落位、空间分析全都靠它打底。实际操作中我发现大部分人在拿到 shp 后的第一个上午都是在跟编码乱码、坐标偏移、属性字段对不上搏斗真正开始画图反而很晚。广东这个省的数据尤其有特点行政区划调整频率高、沿海岛屿多、水道纵横边界几何复杂度远高于内陆省份。哪怕只是画一张“广东省各地市销售额热力图”用市级边界还是县区级边界结论和观感都完全不同。这篇文章按真实动手顺序来讲文件怎么选、坐标和编码怎么排查、业务数据怎么拼接、常见的坑怎么绕开最后落到一条能长期复用的预处理流水线上。2. 选对边界层级和文件版本拿到shp后的前置检查清单2.1 认识shp文件家族一个文件夹里一整套缺一个都打不开Shapefile 往往让人误以为是一个文件实际展开后是一组文件的总和。我只拷贝那个后缀是.shp 的文件给对方十次里有八次对方打不开或者图形和属性对不上。拿到手的正确操作是先看整个文件夹确认构成文件齐不齐。扩展名作用缺失后果.shp几何坐标实体无法读取图形.shx几何索引多数GIS软件拒绝打开.dbf属性表村地名和代码属性丢失.prj坐标参考系描述坐标系未知地图错位.cpg字符编码声明乱码问题难排查.sbn / .sbx空间索引可选部分软件性能下降在 Linux 下拿到压缩包第一件事就是列目录看看有没有那种体积为 0 的空 .prj 文件ls -lh guangdong_shp/没有 .prj 时绝大多数软件会把数据当 WGS84 地理坐标来处理真实数据如果有投影地图整体就飘了。还有一个隐蔽情况.cpg 里写的是 “UTF-8”但 dbf 实际是 GBK这种情况必须以实际读出来的结果为准不能只信声明文件。2.2 省、市、县、镇街底图怎么选一个场景对应一个层级广东行政边界按层级划分常见的是省级轮廓、地级市边界、县区级边界、镇街级边界再往下还有村居界但日常项目很少碰。不同层级的数据体积和几何复杂度差距非常大镇街级的文件可能比市级大几十倍放进网页端会导致加载卡顿。选层级的原则很简单展示目的决定层级。全省维度做热力图市级最合适要做招商引资、人口统计之类的县区对比就用县区级涉及具体规划或者网格化管理才动用到镇街层。使用场景推荐层级原因全省大屏概览地级市文件小渲染快省内区域对比分析地级市视觉要素少信息清晰县区指标空间分布县区级能表现区域不均衡镇街规划、人口密度镇街级网格细适合统计计算在线地图交互展示县区级为主平衡精度与加载性能属性表里的字段又是另一层坑。旧数据常见 ADCODE99、PAC 这类历史字段新一点的会用 GBcode 或者紧跟国标的代码字段。优先用名字能对上最新行政区划代码的字段。拿到文件后我会先跑一个统计脚本把每个字段的唯一值数量打出来快速定位哪个是名称、哪个是代码import geopandas as gpd # 第一次读取先试gbk广东旧数据多 gdf gpd.read_file(gd_city.shp, encodinggbk) print(字段列表, gdf.columns.tolist()) for col in gdf.columns: if gdf[col].dtype object: print(col, 唯一值数:, gdf[col].nunique(), 示例:, gdf[col].iloc[0])这段代码的作用是让数据结构在五分钟内现出原形。字符串字段里唯一值数量接近地市数量的多半是名称或代码字段。打印出的示例值如果是一串数字那就是行政区划代码如果是中文就是地名。把这两个字段定位出来后续所有拼接和出图都有了锚点。参数说明encodinggbk只是第一轮尝试。如果打印结果还是乱码就换成gb18030或utf-8再读。代码里的iloc[0]是打印第一行数据帮助快速判断字段内容。判断字段比直接画图更值得花时间因为字段认错后面所有结果都是错的。2.3 坐标系与编码先看crs再读dbf少走一半弯路拿到广东的 shp先验证几何范围是否合理。广东省陆地范围大体在东经 109 到 117 度、北纬 20 到 25 度之间加上海岛会到更南的位置。如果total_bounds打出来是几十万几百万的数值说明不是经纬度坐标而是投影坐标这个判断决定了后面怎么做变换。# 打印坐标参考系和边界范围 print(当前坐标系:, gdf.crs) print(几何范围:, gdf.total_bounds)如果 crs 显示为 EPSG:4326那是经纬度格式单位是度如果是 EPSG:4490 或 EPSG:3857说明数据已套用了坐标系或投影。更麻烦的是 .prj 里写 WGS84实际数据却是旧的国家坐标系成果。这种情况下只能通过和在线底图叠加来人工判断偏差再选择正确的转换路径。# 统一到WGS84经纬度便于与在线底图叠加 gdf_wgs84 gdf.to_crs(epsg4326)在线地图底图通常用 Web 墨卡托投影但前端库收到 WGS84 经纬度的 GeoJSON 后会自动完成转换所以数据准备阶段统一到 EPSG:4326 就好没必要提前转 3857。转坐标时记住一句话set_crs是声明坐标系to_crs才是真正的坐标系转换。经常有人在网上抄到set_crs(epsg4326)就以为解决了偏移其实是把原本正确的数据重新标记错了越改越歪。3. 把边界shp接上业务数据静态地图、GeoJSON与在线发布3.1 按行政区划代码拼接业务数据避开名称匹配的坑行政边界最终要跟业务数据合体。拿一张“广东各市 GDP 表”去匹配 shp 属性时直觉是用名称但名称匹配是最大的坑有的表写“梅州”有的写“梅州市”有的写“广东梅州”甚至混入全角空格都看不见。正确做法是走行政区划代码。import geopandas as gpd import pandas as pd # 读取边界指定编码 gdf gpd.read_file(gd_city.shp, encodinggbk) # 模拟一份业务数据包含城市代码字段 biz pd.read_excel(demo_gdp_by_city.xlsx) # 统一类型一边是str一边是int合并结果必然是NaN gdf[code] gdf[GBcode].astype(str) biz[code] biz[city_code].astype(str).str.zfill(4) # 左连接保留全部边界图形 merged gdf.merge(biz, oncode, howleft) print(merged.isna().sum())这段代码最关键的是astype(str)和str.zfill(4)。shp 属性里的代码可能是字符串“4401”也可能是整数 4401业务系统导出时 Excel 又可能把文本代码自动转成数字。三边不统一合并结果就全是空的看起来还找不到原因。zfill(4)是把位数补到4位广东地市代码正好是4位。参数说明howleft表示以左侧边界表为准业务数据缺失的市仍然保留轮廓显示为空白。如果用 inner join缺失数据的城市会直接从地图上消失变成边界上的一个洞这种错误在大屏上特别显眼。合并后isna().sum()能检查每个字段缺失数量数值偏大就回头核对代码位数和空格问题。3.2 用GeoPandas出一张能见人的统计地图数据合并完毕下一步是快速出图验证。GeoPandas 直接调用 Matplotlib 画图能在交底图给前端之前就发现问题比如颜色分级是否合理、边界是否连贯。import matplotlib.pyplot as plt fig, ax plt.subplots(figsize(10, 8)) merged.plot(columngdp, cmapOrRd, legendTrue, edgecolorblack, linewidth0.3, axax) ax.set_title(广东省各地市GDP模拟数据) ax.set_axis_off() plt.savefig(guangdong_gdp.png, dpi200, bbox_inchestight)columngdp指定填充颜色的字段cmapOrRd选连续红黄色带适合表达总量大小。edgecolorblack给每个市加上边界线不然相邻区域会连成一片看不出行政区划的区分。set_axis_off()去掉默认的经纬度坐标轴线否则图片下方会出现一排坐标数字放到报告里显得很业余。这里有一个常见误区直接把整个 GeoDataFrame 丢给plot如果原始数据里混入了 MULTIPOLYGON 和 POLYGON 混合几何画出来经常会缺一块或重叠一部分。先用merged.geom_type.value_counts()检查几何类型分布再做统一处理能避免出图时出现莫名其妙的空洞。3.3 从shp到GeoJSON坐标转换与文件轻量化网页端用不了 shp 直接渲染一般要先转 GeoJSON。GeoPandas 一条命令就能转但直接转出来的文件往往很大广东沿海县区的边界线一个面几 MB 都不稀奇。# 只保留需要的字段再导出 merged_selected merged[[name, code, gdp, geometry]] merged_selected.to_file(guangdong_gdp.geojson, driverGeoJSON) # 简化几何后导出体积能压掉一半以上 light merged_selected.copy() light[geometry] light.geometry.simplify( tolerance0.002, preserve_topologyTrue ) light.to_file(guangdong_gdp_light.geojson, driverGeoJSON)simplify使用的是道格拉斯-普克算法tolerance0.002在经纬度单位下大约是百米级别对省市边界来说肉眼几乎无感。preserve_topologyTrue必须带上防止简化后相邻多边形的边界互相穿插。对县区级数据先试用 0.001再根据效果调到 0.002 或 0.003。如果项目没有 Python 环境用 GDAL 的命令行也能完成同样的转换ogr2ogr -f ESRI Shapefile gd_city_4326.shp gd_city.shp -t_srs EPSG:4326 -lco ENCODINGUTF-8这里-t_srs EPSG:4326是转换坐标系-lco ENCODINGUTF-8是把属性编码统一成UTF-8。命令行处理大文件比 Python 快且不依赖 geopandas 那一串复杂的底层库适合在服务器上用脚本批量跑。4. 避坑指南广东边界shp最常见的5类翻车与排查记录4.1 地名全部乱码图上能画、属性不能读现象用 ArcGIS 或 QGIS 打开 shp地图轮廓正常但属性表里的中文名称变成“口口口”或乱码。原因.dbf 属性表用 GBK 或 GB2312 编码软件默认按 UTF-8 读取或者反过来数据是 UTF-8老软件按 GBK 读取。广东省级和市级旧数据多以 GBK 为主但近年新发布的成果有不少是 UTF-8。解决先看同目录的 .cpg 文件内容。如果写着 GBK 或 936就用 GBK 读取。GeoPandas 里指定编码gdf gpd.read_file(gd_city.shp, encodinggbk)在 QGIS 中可以在打开矢量图层的对话框里手动把字符编码改成 GB2312。没有 .cpg 时直接两种编码各试一次哪个打开不乱码就用哪个。不要在中途手工另存 dbf 来“修复编码”那样很可能损坏字段结构。4.2 边界整体偏移地图落到错误的位置上现象行政边界和在线底图叠加广东的轮廓整体平移了几百米甚至几公里海岸线和真实地形对不上。原因坐标参考系信息错误或缺失。没有 .prj 文件软件默认按 WGS84 解析而数据本身可能是 CGCS2000 高斯投影、北京54 或西安80 坐标系成果各坐标系之间的差异在广东沿海地区非常明显。解决先打印 crs 和 total_bounds 判断实际情况。如果确认是投影坐标先设置正确的坐标系再转换到 WGS84。# 广东省常见的CGCS2000高斯克吕格投影 gdf gdf.set_crs(epsg4547, inplaceFalse) gdf_wgs84 gdf.to_crs(epsg4326)注意set_crs与to_crs的区别。前者告诉程序“这个数据原来的坐标系是什么”后者才做真正的数学转换。很多网上抄来的代码把set_crs(epsg4326)当作修偏移实际是把正确数据标记错了越搞越歪。4.3 相邻市县的边界之间有缝隙或互相重叠现象放大地图两个区县的交界处有白色细缝或者两个面互相覆盖颜色叠在一起花掉。原因不同图层数据采集年份不一致拼接时没有做拓扑检查。珠三角河网地区和沿海岸线是重灾区因为水岸线经常变化新旧版本的边界文件合在一起会出现间隙。解决用 buffer(0) 做一次微拓扑修复gdf[geometry] gdf.geometry.buffer(0)零距离缓冲的原理是让每个多边形向外扩张一个极小的量把浮点误差导致的细缝消掉同时修正部分自相交问题。缝隙较大时 buffer(0) 不够需要配合 QGIS 的处理工具箱里的“修复几何”工具。要导入 PostGIS 的数据建议先执行一次 ST_MakeValid再从数据库取数。4.4 行政区划代码对上了但地名和最新区划不一致现象属性表里某个代码对应的是旧地名实际区划已经撤并或更名。原因行政区划一直在变。广东近年也有撤市设区、街道合并的调整。不同出版社或不同年份的数据集采用的区划版本不一致。解决建一个简单的校对流程。先看 shp 的出版日期或数据时间戳再打开最新版的行政区划代码表核对代码前6位是否一致。遇到模糊情况宁可重新找一份新数据也不要沿用旧文件拼接新图表不然地图上一个标着旧名字的区域会让整个项目的可信度被打折。4.5 网页端加载GeoJSON卡到崩溃现象GeoJSON 文件动辄几 MB 到几十 MB浏览器加载慢缩放地图时明显掉帧。原因边界几何顶点太密。特别是沿海县区海岸线包含大量微小转折多边形顶点数轻松上万导致 GeoJSON 体积膨胀。解决发布前做几何简化gdf_simple gdf.copy() gdf_simple[geometry] gdf_simple.geometry.simplify( tolerance0.003, preserve_topologyTrue ) gdf_simple.to_file(gd_city_light.geojson, driverGeoJSON)对市级边界tolerance 从 0.002 开始能接受就试 0.005文件体积能压掉三分之二以上。交互频繁的在线地图还可以再往前走一步发布成矢量瓦片按需加载边界首屏速度会有质的提升。小团队项目用 simplify 就足够了先不必上瓦片方案。5. 进阶把边界shp的预处理做成一条固定流水线当行政区划 shp 更新频率上来以后重复劳动就成了最大的时间成本。我习惯把坐标转换、编码统一、几何简化、字段瘦身这些步骤写成一个固定函数每次拿到新数据跑一遍输出前端直接可用的 GeoJSON。import geopandas as gpd def pipeline_guangdong(src_shp, output_geojson): # 1. 读取先试utf-8失败回退gbk try: gdf gpd.read_file(src_shp, encodingutf-8) except UnicodeDecodeError: gdf gpd.read_file(src_shp, encodinggbk) # 2. 坐标系统一尽量用geopandas的crs判断 if gdf.crs and gdf.crs.to_epsg() ! 4326: gdf gdf.to_crs(epsg4326) # 3. 字段瘦身只保留名称、代码和几何 keep_cols [name, code, geometry] gdf gdf[[c for c in gdf.columns if c.lower() in keep_cols]] # 4. 修复几何简化边界 gdf[geometry] gdf.geometry.buffer(0) gdf[geometry] gdf.geometry.simplify( tolerance0.002, preserve_topologyTrue ) # 5. 导出 gdf.to_file(output_geojson, driverGeoJSON) print(输出完成:, output_geojson) pipeline_guangdong(gd_city.shp, gd_city_light.geojson)这个函数把最容易出错的几个环节都做了保护。编码读取有 try/except 兜底坐标系有 crs 判断字段只保留常用列避免导出超大属性表几何修复和简化一步到位。团队里任何人拿到新数据跑一下这个函数就能交付一个能用的轻量文件。对于只需要陆地主轮廓的场景还要加一道岛屿过滤。广东海岛众多如果做的是大屏灰度底图小岛会变成视野里的噪点。在简化前按面积过滤掉碎片面gdf[area] gdf.geometry.area gdf gdf[gdf[area] 0.001] # 阈值需根据坐标系调用于过滤细小岛礁这里面积阈值要和坐标系单位对应。数据统一到 WGS84 后面积的单位是平方度一个普通县域大约是 0.3 平方度量级过滤到 0.001 以下就能去掉绝大多数细微碎岛。需要保留但不想显示太多细节时把简化容差加大让这些小岛合并成粗糙的小块视觉上干净很多。我现在每个新项目都先运行这套流程然后在结果文件上做三件事抽查两三个相邻县的边界是否贴合对比新旧版本地名变化把输出的 GeoJSON 体积打印出来确认在可接受范围。这套流程跑顺以后返工率比我以前手动操作少了很多。边界数据看起来简单真正埋着的问题大多是坐标系、编码、拓扑这几类提前建好流水线后面就不用每次都在同一个地方重蹈覆辙。希望这套落地流程对你也有帮助。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

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

尧图内容编辑团队

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

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

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

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

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

网站改版的5个关键决策

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

获取专属建站方案

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

立即免费咨询