首页 / 资讯中心 / 文章详情

九大流域shp数据处理:QGIS与geopandas完整指南

九大流域shp数据处理:QGIS与geopandas完整指南 ★ FEATURED ARTICLE
简介中国九大流域shp.zip是一份面向GIS与R用户的矢量地理数据包覆盖长江、黄河、珠江、淮河、海河、辽河、松花江、太湖、闽江九大流域边界。包内已为每个流域补充name属性字段可直接在ArcGIS、QGIS中加载显示名称也便于用sf、ggplot2等R包进行面积统计、空间叠加与可视化分析。压缩包共8个文件包含.shp几何、.dbf属性、.prj投影坐标及.sbn/.sbx空间索引等结构完整总大小约473KB轻量易用。该资源已有8600余人学习下载适合地理、环境、水利等专业学生和研究人员用于流域制图、水文分析或教学演示。借助这些矢量边界可快速开展九大流域的对比统计与专题绘图节省数据预处理时间。1. 拿到“中国九大流域shp.zip”先别急着拖进GIS做水文分析、流域生态评估、水资源分区统计或者单纯想画一张“全国九大流域”的总图时很多人第一反应是去自然资源数据类站点找现成的流域边界。搜到的往往就是一个叫“中国九大流域shp.zip”的老压缩包里面装着一套看起来能用的矢量数据。这个包在行业里流传很广但你直接拖进 ArcGIS 或 QGIS十有八九要出问题属性表乱码、面积算出来只有几万平方公里、流域边界跟省界对不上。这不是数据坏了而是你还没搞清楚包里那几份文件之间的关系以及这套流域边界是按什么口径画出来的。这篇文章就顺着“拿到包之后怎么处理”这条线把从解压到出图的完整路径走一遍顺手把最容易踩的坑标出来。2. 九大流域的划分口径与shp文件结构先看懂包里的东西再动手2.1 流域分区的两种口径水资源一级分区与自然流域的差别开始动数据之前要先把“九大流域”这个词拆清楚。你搜到的“中国九大流域shp.zip”多数版本采用的是水利行业常用的水资源一级分区口径也就是把全国陆地按流域水系划分成若干大区通常包括长江、黄河、珠江、松花江、淮河、海河、辽河再叠加东南诸河、西南诸河有的版本并入西北内陆河目录上会略有出入所以不同压缩包解压出来的图层数量和名称并不完全一致。这套口径是服务于水资源统计和管理用的不等于严格水文意义上的集水区。这里有个关键区别自然流域也叫汇水区是以地形分水岭为边界从 DEM 里用水文分析工具自动提取出来的而水资源一级分区是管理和统计口径边界往往沿着水系、行政区域或者山脉走向做了宏观划分局部地方跟真正的地形分水岭未必重合。所以你拿这份数据和某条河流的实测流量站控制面积去对比对不上是正常的不是数据有错。理解这一点后面很多“看起来有问题”的现象就都能解释通了。另外这一类 zip 里可能有两种组织形式一种是把整个九大流域合并成一个 shp属性表里每条记录是一个流域靠字段区分另一种是每个流域单独存一个 shp九到十个文件堆在同一个压缩包里。这两种情况处理方式完全不同所以解压后第一件事不是打开 GIS而是先看文件结构。2.2 解压后先做三件事看文件清单、看坐标系、看属性表我在拿到任何矢量压缩包时会习惯性地在终端里先看一眼压缩包里到底有什么再决定怎么解压。以“中国九大流域shp.zip”为例最常见的命令是# 先列出压缩包内容不急着解压 unzip -l 中国九大流域shp.zip # 确认有 shp 文件后解压到单独目录 unzip 中国九大流域shp.zip -d shp_dir这里并不是随便敲两条命令凑步骤。unzip -l能让你在解压前就看到文件数量、大小和目录层级避免解压出一堆乱糟糟的文件之后还得回过头来整理。如果压缩包里每个流域一个 shp你会看到十几个.shp后缀的文件如果只有一个主 shp那文件数量会少很多但伴生文件齐全。解压之后我一般会按顺序做三件事。第一个是打开.prj文件用文本编辑器就行比如记事本或者 VS Code。.prj里记录的是坐标系信息常见的老包用的是 WGS84 地理坐标系也就是GEOGCS[GCS_WGS_1984]开头的文本也有部分包用了 CGCS2000或者更老旧的北京54/西安80。这个直接决定了你后面加载底图时会不会偏移。第二个是看有没有.cpg文件。.cpg文件很小里面通常写着UTF-8或GBK它告诉软件属性表的 dbf 文件是什么字符编码。如果没有这个文件大概率 dbf 是 GBK 编码你在 QGIS 里直接打开属性表就会看到中文乱码。第三件事是确认 shp 文件的字段结构。用 QGIS 拖进去之前我会先用 Python 快速看一眼字段名因为不同版本的包字段名差异很大——有的叫NAME有的叫流域名称还有的叫NAME_CN。不知道字段名后面的筛选和统计脚本就没法写。2.3 shp 的伴生文件认识dbf、shx、prj、cpg 千万别丢很多新手会把 zip 里的 shp 文件单独复制出来用其他文件都不管这是最常见的翻车点。Shapefile 不是单文件格式一个完整的 shp 至少要带上.shx几何索引和.dbf属性表才能正常读取.prj决定坐标系的正确识别.cpg决定中文乱码与否还可能附带.sbn/.sbx空间索引等文件。单独拷走一个.shpQGIS 里能识别几何但属性表是空的坐标系也会被默认成未知。实际操作中更隐蔽的一个问题是改文件名。有人会把“九大流域shp”重命名成自己顺手的名字结果只改了.shp后缀的主文件名忘了同步改.dbf和.shx的名字软件加载时就报“文件无法打开”因为它在找同名的 dbf 文件找不到。所以解压之后文件名一个字符都不要动要改也要成组地改。如果你发现解压出来的包里只有一个.shp文件没有任何伴生文件那基本可以断定这个包是被人从某些在线转换工具里导出后重新打包的多半已经丢失了属性表。这种包能不能用几何边界可以看但没法按流域筛选也没法读名字字段建议放弃返回去重新找完整包。3. 在QGIS里完成流域筛选与出图的最小流程3.1 加载zip里的shp最小操作与坐标系的兜底处理QGIS 是处理这套数据最顺手也最稳妥的工具原因有两个一是它能直接读取 zip 内的 shapefile不用解压也能拖拉加载二是它对坐标系缺失的容错能力比 ArcGIS 强会弹出对话框让你手动指定坐标系。我个人的习惯是先解压再加载因为后面做筛选和导出时路径管理更清晰。加载方式有三种直接把shp文件拖进 QGIS 窗口通过菜单“图层→添加图层→添加矢量图层”选择文件或者把整个 zip 文件拖进 QGIS。第三种方式在 QGIS 3.x 里会直接识别出 zip 内的矢量文件但有个问题如果 zip 里同时有多个 shpQGIS 会把它们全部加载出来而你只想先加载主文件。所以拖 zip 适合快速查看不适合精细操作。加载后第一件事是看左下角的坐标系显示。如果显示EPSG:4326说明.prj文件被正确读取了如果显示“未知 CRS”你需要手动兜底。老包常见 WGS84如果确定原始数据是地理坐标直接选WGS 84EPSG:4326就行。注意这一步选错的话图不会立刻有肉眼可见的问题但后续叠加在线底图时会发现整个边界平移了几百公里那时候再返工就晚了。# 在QGIS中按文件类型加载shp时编码和CRS设置在“数据源管理器”里完成 # 编码(Encoding)选 GBK 或 UTF-8与.cpg内容保持一致 # 坐标系(CRS)选 EPSG:4326若prj显示CGCS2000则选EPSG:4490为什么特别强调编码要和.cpg一致因为 QGIS 读取 dbf 时默认按 UTF-8 解码而老数据大多是 GBK。加载时如果发现属性表里的中文变成乱码不需要重新加载右键图层打开“图层属性→数据源”把编码改成GBK或者GB18030点“应用”就能恢复。这是 QGIS 处理老 shp 最实用的一个功能。3.2 按字段筛选出一个流域用表达式选中目标再另存加载进来后你面对的可能是一整张全中国的流域面属性表里有九到十条记录。如果只想保留珠江流域用 QGIS 的表达式筛选比手动选择要可靠得多。右键图层→“筛选”打开查询构建器填入NAME LIKE %珠江%或者如果字段名是中文写成流域名称 珠江表达式里的字段名要跟属性表里完全一致所以在此之前按 F6 打开属性表先看一下字段到底叫什么。LIKE %珠江%用的是模糊匹配能兼容“珠江流域”“珠江区”这类带前后缀的写法等号则是精确匹配字段值里多一个空格都会匹配不上导致筛选结果为空。如果你发现等号匹配不出任何记录原因多半是值里有空格或不可见字符换成LIKE基本都能绕过去。筛选完成之后不要把筛选状态当成数据修改它只是在视图层面做了隐藏。要导出成独立的单流域图层用“图层→导出→另存为要素类”格式选 GeoJSON 或新的 shp坐标系选EPSG:4326如果要后续做面积统计可以顺便选好目标投影但我不建议在导出时转投影后面用批量脚本处理更可控。3.3 用字段计算器补一个面积字段QGIS里的面积统计方法很多人在 QGIS 里看属性表没有面积字段就想着用测量工具手动框选流域面积这完全是多余的。QGIS 的表达式$area可以直接按图层当前坐标系计算面积但如果图层是地理坐标单位是度默认的计算方式会近似失真。正确做法是先加一个面积字段再用投影转换后的几何去算。实际操作流程打开属性表点左上角“打开字段计算器”新建字段名area_km2类型选“十进制数(浮点型)”精度设 15位宽设 10表达式填$area / 1000000这里有个重要细节$area用的坐标系不是图层显示时的 CRS而是 QGIS 自动为“椭球体面积计算”选的参考椭球。在 QGIS 3.x 默认设置下$area返回的是基于图层 CRS 的平面面积地理坐标系下会导致面积严重偏小但如果你在“项目属性→测量”里开启了“椭球体计算”则返回真实椭球面积。这个默认设置每个版本还不一样所以我一般不靠$area而是把图层投影到 Albers 等积投影后再计算方法在下一章的 Python 部分统一讲。4. 用geopandas批量处理九大流域面积计算与格式转换4.1 用geopandas读入并查看数据结构先打印字段再看内容如果你要处理的不止一个流域而是要遍历全部分区做批量统计、分类导出或转格式QGIS 的点选操作就显得笨重了。我的做法是用 Python 的 geopandas 库把 shp 读进 DataFrame再按流域名称做循环处理。先看基础读取代码import geopandas as gpd # 读入shpencoding根据.cpg或实际乱码情况调整 gdf gpd.read_file(shp_dir/中国九大流域.shp, encodingutf-8) # 打印字段名和每段数据的前两行 print(gdf.columns.tolist()) print(gdf.head(2).to_string())这段代码的关键在encoding参数。很多新手用 geopandas 读老 shp 时发现中文全是乱码就是这个参数没设置对。如果 dbf 内部是 GBK第一次读取时就把encodingutf-8改成gbk或者gb18030。gb18030比gbk覆盖面更广兼容藏文、维吾尔文等少数民族文字处理中国流域数据时更稳。print(gdf.columns.tolist())这行代码务必先跑因为不同压缩包的字段名差异太大。有的包字段叫NAME有的叫name还有的是拼音缩写LY_NAME或中文流域。后续所有筛选取值都依赖这个字段名不知道的话后面代码跑出来全是空结果。4.2 计算流域面积为什么必须投影到Albers等积后再算拿到读入后的gdf直接取gdf.geometry.area是很多人的习惯性操作。但要看清楚如果gdf.crs是EPSG:4326度为单位面积的单位就是“平方度”一个平方度在不同纬度代表的真实面积完全不同数值没有任何参考意义。正确做法是先投影到适合全国范围的等积投影。# Albers等积圆锥投影覆盖中国主体的常用参数 albers projaea lat_125 lat_247 lat_00 lon_0105 datumWGS84 gdf_albers gdf.to_crs(albers) gdf_albers[area_km2] gdf_albers.geometry.area / 1_000_000 # 只看面积列和名称列 print(gdf_albers[[NAME, area_km2]].sort_values(area_km2, ascendingFalse))这里lat_1和lat_2是两条标准纬线25 度和 47 度基本覆盖了中国大陆主体lon_0105是中央经线放在全国中心附近能减少东西两侧的变形。datumWGS84保证基准一致。如果数据源本身是 CGCS2000 坐标系把datumWGS84换成datumCGCS2000也行甚至更贴合原始数据。为什么要用等积投影因为只有等积投影才能保证面积量算的准确性。投影转换之后geometry.area算出来的就是平方米除以 1000000 得到平方公里。这个数值跟统计年鉴里的流域面积如果有出入多半是因为前面章节提到的口径问题——水资源一级分区用管理边界代替了地形分水岭面积略大或略小都正常。4.3 批量筛选并导出GeoJSON按名称循环写文件日常工作中我遇到最多的需求是把九大流域从一张大 shp 里拆成单独的小文件或者把某个流域挑出来给同事做二次加工。用循环解决这个需求非常干净import os os.makedirs(out, exist_okTrue) # 根据自己的字段名调整这里假设叫NAME name_field NAME # 手工整理一份流域关键词名单 targets [长江, 黄河, 珠江, 松花江, 淮河, 海河, 辽河] for kw in targets: layer gdf[gdf[name_field].str.contains(kw, naFalse)] if len(layer) 0: print(f未找到{kw}) continue # 转成WGS84再导出方便在网页地图里使用 layer_wgs layer.to_crs(EPSG:4326) out_path fout/{kw}.geojson layer_wgs.to_file(out_path, driverGeoJSON) print(f已导出{out_path}共 {len(layer)} 个要素)这里str.contains(kw, naFalse)的naFalse必须写否则字段里有一个空值就会整行报错返回 NaN。to_crs(EPSG:4326)这一步是为了保证导出的 GeoJSON 能被 Leaflet、Mapbox 或各种 Web GIS 直接使用不转的话你导出的是 Albers 投影坐标放到在线地图上会错位到海里。如果你要导出的对象本身就是一套数据而非单图层可以在循环外面先dissolve一下再导出# 不建议直接使用仅当原始数据每个流域被拆成多个面片时 gdf_dissolved gdf.dissolve(byname_field, as_indexFalse)dissolve之后要素数量会从几十个合并到跟流域数量一致每个流域变成一块完整的面这在后期统计和配色时会更友好。但要注意dissolve会丢掉除分组字段外的所有属性列所以如果还想保留其他信息得先自己拼回去。5. 避坑流域数据最容易翻车的五个细节5.1 属性表中文乱码或字段名变成问号现象在 QGIS 属性表里NAME字段里的中文显示成???或者类似“浣犲ソ”的乱码符号在 geopandas 里print(gdf.head())输出也是同样的乱码。原因shp 的 dbf 属性表是 GBK 编码而 QGIS 和 geopandas 默认都用 UTF-8 读取。解决QGIS 侧在加载时把编码改成GB18030Python 侧在read_file里加encodinggb18030。如果加了还是乱码检查.cpg文件内容有的包是CP936对应编码也是 GBK不要被不同的写法搞混。5.2 坐标系看起来是对的但量出来的面积和长度完全不对现象加载时显示EPSG:4326叠加在线底图也对得上但算出来的面积只有真实值的零头。原因底图对得上是因为 Web 底图本身也是地理坐标系的球面墨卡托或 WGS84 瓦片视觉上不偏移但直接对EPSG:4326的几何要素计算面积单位是平方度不是平方米。解决回到第 4.2 的方法投影到 Albers 等积投影后再算面积。这是我被问过最多的问题也是 GIS 数据处理的经典“玄学”之一。5.3 流域边界跟省界、河流位置对不齐现象把流域边界跟水系线叠加时发现边界线和河道在山区明显偏离并不是贴着分水岭走。原因这套数据是水资源管理口径的一级分区不是基于 DEM 自动提取的汇水区。它的边界在部分区段可能沿用了行政界线或者做了简化处理所以局部对不上地形很正常。解决如果你做的是严格的水文分析需要用流域出水口和 DEM 重新提取集水区如果只是做宏观统计和出图展示这份数据的精度足够不用纠结边界细节。5.4 一个流域被拆成很多个小面片统计时数量翻倍现象属性表里“长江流域”有几十条记录每条的几何都是小碎面直接groupby(NAME).sum()算出来的面积重复累加。原因原始数据可能来源于分省分区拼合同一流域跨多个省份或多个二级区所以被拆成了多个要素。解决先用dissolve(byname_field)合并再计算面积。如果你还需要保留子区域之间的区分就不要 dissolve而是先加一列面积再按流域分组求和。两个方向都行但千万别拿碎面直接当完整流域边界往下游用会多算或者漏算。5.5 不同来源的包字段名完全不一样脚本跑一次就报错现象你在 A 版本上写好gdf[NAME]换到 B 版本运行直接KeyError。原因这套 shp 没有统一的权威字段命名规范流传版本很多有的字段是中文有的是英文缩写还有的带上拼音前缀。解决别假定字段名在脚本开头动态探测字段。常见做法是打印gdf.columns.tolist()后优先匹配名称特征for col in gdf.columns: if name in col.lower() or 流域 in col: name_field col break else: name_field gdf.columns[0] print(使用字段, name_field)这段逻辑不算严谨但能覆盖大部分版本。如果都没有明显名称特征那就先去属性表里人工确认一次再写死字段名。强依赖字段名的脚本往往不是脚本写错而是数据源换了个包导致字段对不上。6. 把流域边界做成一张能汇报的正规图水系叠加与打印布局拿到了边界数据也验证过面积没问题最后一步往往是出图汇报。我一般会做一张叠加了主要水系、带图例和比例尺的“九大流域分布图”用来放进报告或 PPT。QGIS 打印布局里几个地方值得留意。先把水系线数据拖进来通常是全国河流 polyline 图层再从属性表里按河流等级筛选出干流或一级支流。表达式可以用等级 3这类条件取决于你手里的水系字段。叠加顺序是底图放最下面、流域面居中、水系线在最上面。流域面的配色建议不要用 QGIS 默认的随机彩色而是选一套色带按NAME字段分类显示同一条流域内如果有多段要素颜色要统一。这个在“图层属性→符号化→分类”里按名称字段设置即可。打印布局里的几个关键参数布局窗口尺寸选 A3 横向比例尺手动调到能完整容纳全国的范围通常 1:12,000,000 附近指北针放在右下角图例只显示图层名称不要勾选图层里的每一项分类值。网格线可以开经纬网间隔 10 度标注格式选“十进制”。最后一步是加数据来源注记我是习惯在右下角写“数据来源全国水资源一级分区”这既是职业习惯也方便日后追溯数据版本。这套流程走下来你拿到“中国九大流域shp.zip”之后从检查文件结构到批量算面积、拆分导出、出图汇报基本能形成一条不用返工的流水线。我最深的一条教训是别迷信 zip 自带的那份说明文档很多包里根本没有更别在没确认坐标系和编码之前就开始做样式和标签数据底子不对后面全是返工。希望这篇能帮你在类似的流域数据处理上少折腾几个来回。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站