资讯详情

粤港澳大湾区shp数据全攻略:从坐标系到可视化

📅 2026/10/29 16:25:30 | 华诺云谱 👁 阅读
粤港澳大湾区shp数据全攻略:从坐标系到可视化
简介这份粤港澳大湾区shp数据面向从事GIS制图、空间分析与区域规划的研究者、学生及从业者提供可直接加载的矢量底图解决大湾区跨城市边界数据获取零散、格式不统一的问题。资源包共20个文件以shp、shx、dbf、prj等Shapefile核心组件为主辅以sbx、sbn空间索引及xml元数据压缩包约272KB体量轻便便于快速导入ArcGIS、QGIS等平台进行可视化与叠加分析。目前已有291人学习下载适合需要快速搭建大湾区制图底图或开展空间统计的初中级用户。数据覆盖粤港澳大湾区整体范围及香港、澳门等局部线要素属性表与投影信息完整可直接用于专题图制作、行政区划展示与空间关系验证省去自行搜集与坐标校正的环节为区域研究提供规范、即用的基础地理数据支撑。1. 拿到粤港澳大湾区 shp 数据后先搞清楚它能干什么做 GIS 可视化的人多半有过这种经历底图配好了、配色调顺了结果卡在边界数据上——要么行政区划对不上要么海岸线缺一块要么投影一叠加就飘到几百公里外。粤港澳大湾区 shp 数据解决的正是这个前置问题它把广州、深圳、珠海、佛山、惠州、东莞、中山、江门、肇庆九个城市以及香港、澳门两个特别行政区的行政边界、海岸线、岛屿轮廓整理成标准矢量图层直接拖进 QGIS、ArcGIS 或 GeoPandas 就能用。适合做区域经济热力图、交通可达性分析、城市扩张监测、专题地图出图的人。它不是一张图而是一套可编辑、可裁剪、可叠加的几何底料你后续所有空间统计和可视化都建立在它之上。2. 拆开这份 shp 数据图层结构、坐标系与字段设计2.1 常见图层构成与属性字段一套完整的粤港澳大湾区 shp 数据通常不是一个孤零零的.shp文件而是按行政层级拆成多个图层。常见做法是分成市级边界、区县级边界有的还会附带海岸线和主要岛屿。每个图层对应一组同名文件.shp存几何、.dbf存属性、.shx存索引、.prj存投影信息。少一个.prj坐标系就得靠猜这是新手最容易翻车的地方。属性表里一般会有这些字段字段名含义示例值NAME城市中文名广州市NAME_EN城市英文名GuangzhouADCODE行政区划代码440100PROVINCE所属省级单位广东省LEVEL行政级别city / districtAREA_KM2面积平方公里7434.4字段命名不同版本会有差异但NAME和ADCODE基本是标配。ADCODE是后续做数据关联的关键——你要把统计年鉴的 GDP、人口数据挂到地图上靠的就是它。2.2 坐标系WGS84 还是 CGCS2000这是整个流程里最容易被忽略、后果最严重的一环。粤港澳大湾区 shp 数据常见的坐标系有两种WGS84EPSG:4326和 CGCS2000EPSG:4490。两者在地图上看差别不大但做面积计算或叠加其他数据时差之毫厘谬以千里。如果你只是做展示出图WGS84 够用。但如果要算真实面积、做缓冲区分析必须投影到平面坐标系。大湾区常用的投影是 UTM 49NEPSG:32649或 CGCS2000 3度带高斯克吕格投影。判断当前数据是什么坐标系最直接的办法是看.prj文件内容或者在 QGIS 里右键图层属性查看。# 用 ogrinfo 快速查看 shp 的坐标系和字段信息 ogrinfo -al -so gba_city.shp # 输出里重点关注这几行 # Geometry: Polygon # Feature Count: 11 # Extent: (111.xxx, 21.xxx) - (115.xxx, 24.xxx) # Layer SRS WKT: GEOGCS[GCS_WGS_1984, ...]ogrinfo是 GDAL 自带的命令行工具-al表示列出所有要素-so表示只输出摘要不输出几何。如果你看到Layer SRS WKT里写着WGS_1984那就是地理坐标系单位是度不能直接用来算面积。2.3 用 Python 读取并检查数据完整性实际动手前我习惯先用 GeoPandas 把数据读一遍确认几何有效、字段完整、没有空值。import geopandas as gpd # 读取市级边界 gdf gpd.read_file(gba_city.shp) # 基本信息 print(f要素数量: {len(gdf)}) print(f坐标系: {gdf.crs}) print(f字段列表: {list(gdf.columns)}) # 检查几何有效性 invalid gdf[~gdf.geometry.is_valid] print(f无效几何数量: {len(invalid)}) # 检查空几何 empty gdf[gdf.geometry.is_empty] print(f空几何数量: {len(empty)}) # 查看每个城市的面积度为单位仅作对比 gdf[area_deg] gdf.geometry.area print(gdf[[NAME, area_deg]].sort_values(area_deg, ascendingFalse))这段代码做了四件事确认要素数量是否符合预期大湾区应该是11个城市、检查坐标系是否已定义、排查无效几何、对比各城市面积量级。如果len(gdf)只有9说明香港和澳门可能被单独放在另一个图层里。如果gdf.crs返回None说明.prj文件缺失需要手动指定坐标系。几何无效是 shp 数据的常见病表现为自相交、悬挂节点、重复顶点。GeoPandas 提供了buffer(0)这个经典偏方来修复大部分自相交问题# 修复无效几何 gdf[geometry] gdf.geometry.buffer(0) print(f修复后无效几何: {len(gdf[~gdf.geometry.is_valid])})buffer(0)的原理是把多边形先向外缓冲0距离再收回这个过程会重建拓扑关系把自相交的环理顺。注意它不保证100%修复极端情况还是得回 QGIS 用拓扑检查工具手动处理。3. 从 shp 到可视化投影转换、裁剪与出图全流程3.1 投影转换把度变成米拿到地理坐标系的数据后第一步是投影转换。不转投影就做缓冲区分析等于用尺子量空气。import geopandas as gpd gdf gpd.read_file(gba_city.shp) # 如果 crs 为空先手动指定为 WGS84 if gdf.crs is None: gdf gdf.set_crs(EPSG:4326) # 投影到 UTM 49N适合大湾区 gdf_proj gdf.to_crs(EPSG:32649) # 验证面积单位变成平方米 gdf_proj[area_km2] gdf_proj.geometry.area / 1e6 print(gdf_proj[[NAME, area_km2]].sort_values(area_km2, ascendingFalse)) # 保存投影后的数据 gdf_proj.to_file(gba_city_utm.shp, encodingutf-8)to_crs是 GeoPandas 的投影转换方法参数可以是 EPSG 代码或 proj 字符串。UTM 49N 覆盖东经111°到114°大湾区大部分在这个范围内边缘区域变形可接受。如果你要做跨区域分析可以考虑 Albers 等积投影。保存时加encodingutf-8是为了防止中文属性乱码这个坑后面还会细说。3.2 用 matplotlib 快速出图投影转好后出图就是几行代码的事。但要让图能看还得调几个参数。import matplotlib.pyplot as plt import geopandas as gpd gdf gpd.read_file(gba_city_utm.shp) fig, ax plt.subplots(1, 1, figsize(12, 10)) # 绘制城市边界按面积填色 gdf.plot( columnarea_km2, cmapYlOrRd, edgecolorblack, linewidth0.8, axax, legendTrue, legend_kwds{label: 面积平方公里, orientation: horizontal} ) # 标注城市名 for idx, row in gdf.iterrows(): centroid row.geometry.centroid ax.annotate( row[NAME], xy(centroid.x, centroid.y), hacenter, fontsize9, fontpropertiesSimHei # 中文字体 ) ax.set_title(粤港澳大湾区各城市面积分布, fontsize14) ax.set_axis_off() plt.tight_layout() plt.savefig(gba_area_map.png, dpi300, bbox_inchestight) plt.show()column参数指定填色依据的字段cmap是色带legendTrue自动生成图例。中文标注需要指定fontproperties否则会显示成方框。set_axis_off()去掉坐标轴出图更干净。dpi300保证打印精度。3.3 裁剪只保留研究区范围做具体项目时往往只需要大湾区的一部分。比如研究深圳都市圈就得把其他城市裁掉。import geopandas as gpd from shapely.geometry import box gdf gpd.read_file(gba_city_utm.shp) # 定义研究区范围UTM坐标单位米 # 这里以深圳为中心的大致范围 study_area box(100000, 2480000, 250000, 2600000) # 用矩形裁剪 gdf_clip gpd.clip(gdf, study_area) # 或者按属性筛选 gdf_sz gdf[gdf[NAME] 深圳市] # 保存 gdf_clip.to_file(gba_clip.shp, encodingutf-8)gpd.clip是几何裁剪保留与裁剪框相交的部分。box的四个参数是(minx, miny, maxx, maxy)单位跟数据坐标系一致。如果你只知道经纬度范围得先转成投影坐标再裁剪。按属性筛选更简单但要求字段值精确匹配深圳市和深圳是两个结果。3.4 叠加统计数据的完整链路光有边界没意义真正有用的是把统计数据挂上去。假设你有一份 CSV包含各城市2023年GDP。import pandas as pd import geopandas as gpd gdf gpd.read_file(gba_city.shp) df pd.read_csv(gdp_2023.csv) # 查看两边用于关联的字段 print(gdf[[NAME, ADCODE]].head()) print(df[[city_name, gdp]].head()) # 按城市名关联 merged gdf.merge(df, left_onNAME, right_oncity_name, howleft) # 检查是否有未匹配的记录 unmatched merged[merged[gdp].isna()] if len(unmatched) 0: print(f未匹配城市: {unmatched[NAME].tolist()}) # 出图 merged.plot(columngdp, cmapBlues, legendTrue, edgecolorgray)merge是 pandas 的操作howleft保证保留所有几何要素匹配不上的 GDP 为空。关联字段两边名称可以不同用left_on和right_on指定。关联后一定要检查未匹配记录常见原因是城市名有空格、简称全称不一致、或者 CSV 里压根缺了某个城市。4. 避坑指南shp 数据处理的五个血泪教训4.1 中文乱码dbf 文件的编码陷阱现象用 GeoPandas 读取 shp 后NAME字段显示为广å·å¸这样的乱码。原因shp 的.dbf文件默认用系统编码Windows 下中文常是 GBK而 GeoPandas 默认按 UTF-8 读取。解决读取时指定编码或者用 QGIS 另存为 UTF-8。# 方法一读取时指定编码 gdf gpd.read_file(gba_city.shp, encodinggbk) # 方法二用 ogr2ogr 转换编码 # ogr2ogr -f ESRI Shapefile output.shp input.shp -lco ENCODINGUTF-8如果乱码已经发生且原始数据没备份基本没有后悔药。我现在的习惯是拿到任何 shp 先ogrinfo看一眼编码再决定怎么读。4.2 坐标系丢失.prj 文件缺失现象数据能读进来但gdf.crs返回None做任何空间操作都报错或结果离谱。原因拷贝数据时只复制了.shp、.shx、.dbf漏掉了.prj。或者数据来源本身就没带投影文件。解决根据数据范围判断坐标系手动指定。# 如果确定是 WGS84 经纬度 gdf gdf.set_crs(EPSG:4326) # 如果确定是 CGCS2000 gdf gdf.set_crs(EPSG:4490) # 指定后再转投影 gdf_proj gdf.to_crs(EPSG:32649)判断依据看坐标值范围。经纬度的话 x 在 111-115 之间y 在 21-24 之间。如果是投影坐标数值会是几十万到几百万。指定错了坐标系后续所有分析都是错的。4.3 几何无效自相交与悬挂节点现象做intersection或union时抛出TopologyException或者结果多边形出现奇怪的空洞。原因数据生产过程中数字化误差导致多边形自相交或者相邻多边形共享边不完全重合。解决先用buffer(0)修复再检查。# 修复 gdf[geometry] gdf.geometry.buffer(0) # 如果还有问题用 shapely 的 make_valid from shapely.validation import make_valid gdf[geometry] gdf.geometry.apply(make_valid)make_valid是 shapely 1.8 提供的更严谨的修复方法比buffer(0)更可靠但速度慢一些。数据量大的话建议先buffer(0)批量处理再对残余问题用make_valid。4.4 面积计算单位错误现象算出广州面积是 0.12明显不对。原因数据还是地理坐标系geometry.area返回的是平方度不是平方米。解决先投影再算面积。# 错误做法 gdf gpd.read_file(gba_city.shp) # WGS84 area_wrong gdf.geometry.area # 单位是平方度 # 正确做法 gdf_proj gdf.to_crs(EPSG:32649) area_correct gdf_proj.geometry.area / 1e6 # 平方公里平方度到平方公里的换算不是固定系数因为不同纬度上1度对应的距离不同。所以必须投影没有捷径。4.5 文件体积过大导致读取缓慢现象区县级边界数据加载要等十几秒出图卡顿。原因高精度边界包含大量冗余顶点一个区县可能有几万个坐标点。解决做几何简化在精度和体积之间取平衡。# 简化几何tolerance 单位与坐标系一致 gdf_simplified gdf_proj.copy() gdf_simplified[geometry] gdf_proj.geometry.simplify(tolerance100, preserve_topologyTrue) # 对比顶点数量 print(f原始顶点数: {sum(len(g.exterior.coords) for g in gdf_proj.geometry)}) print(f简化后顶点数: {sum(len(g.exterior.coords) for g in gdf_simplified.geometry)})tolerance100表示100米对于市级展示够用。preserve_topologyTrue防止简化后多边形自相交。如果是做精细分析tolerance 要调小到10米甚至更小。5. 进阶技巧用 shp 数据做空间连接与热力图5.1 空间连接把点数据聚合到面假设你有一批企业注册地址的经纬度点想统计每个城市的企业数量。这就是典型的点面空间连接。import geopandas as gpd import pandas as pd from shapely.geometry import Point # 读取城市边界 cities gpd.read_file(gba_city.shp).to_crs(EPSG:4326) # 模拟企业点数据 points_df pd.DataFrame({ name: [企业A, 企业B, 企业C], lng: [113.26, 114.06, 113.55], lat: [23.13, 22.54, 22.19] }) points gpd.GeoDataFrame( points_df, geometry[Point(xy) for xy in zip(points_df[lng], points_df[lat])], crsEPSG:4326 ) # 空间连接每个点落在哪个城市 joined gpd.sjoin(points, cities, howleft, predicatewithin) # 统计各城市企业数 count joined.groupby(NAME).size().reset_index(name企业数量) print(count)sjoin的predicatewithin表示点在城市多边形内部。howleft保留所有点落在边界外的点城市名为空。如果点正好落在两个城市交界线上可能匹配到两个城市需要去重。5.2 热力图用点密度反映空间聚集有了点数据热力图比单纯的分级填色更能反映聚集特征。import matplotlib.pyplot as plt import geopandas as gpd import numpy as np from scipy.stats import gaussian_kde cities gpd.read_file(gba_city_utm.shp) points gpd.read_file(enterprises.shp).to_crs(EPSG:32649) # 提取坐标 x points.geometry.x.values y points.geometry.y.values # 核密度估计 kde gaussian_kde(np.vstack([x, y])) xi, yi np.mgrid[x.min():x.max():500j, y.min():y.max():500j] zi kde(np.vstack([xi.flatten(), yi.flatten()])).reshape(xi.shape) # 出图 fig, ax plt.subplots(figsize(12, 10)) cities.plot(axax, facecolornone, edgecolorgray, linewidth0.5) ax.contourf(xi, yi, zi, levels15, cmaphot_r, alpha0.7) ax.set_axis_off() plt.savefig(heatmap.png, dpi300, bbox_inchestight)gaussian_kde是 scipy 的核密度估计500j表示生成500个等间距点。contourf画填充等值线alpha0.7让底图边界透出来。带宽参数bw_method可以调整平滑程度默认是 Scott 规则点密集时可能过平滑可以手动设小一点。5.3 验证数据质量的三个习惯从那以后我每次拿到新的 shp 数据都强制走一遍这三步先ogrinfo看坐标系和字段再is_valid查几何最后用total_bounds确认范围是否合理。这三步花不了两分钟但能省下后面几小时的排查时间。尤其是total_bounds如果返回的坐标范围跟预期差了一个数量级那肯定是坐标系出了问题后面所有操作都白搭。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑