信息速览
HydroBASINS 是「世界被水怎么划分」这个问题的一套标准答案。它给出的是多边形:每一个多边形是一块汇水到同一个出口的陆地,边界沿山脊走,出口在最低处。全球陆地被这样切了十二遍,每一遍的颗粒度不同,从数千万平方公里的整块大陆,一路切到平均一百多平方公里的碎块。
十二遍不是十二张互不相干的图。它们是同一套编码的十二个深度,上一层的每一块,恰好等于下一层若干块的并集。这套编码叫 Pfafstetter,是这份数据的骨架,也是它区别于一切「按行政边界切出来的流域图」的地方。
它常被当成河的图来用,其实它画的是地。河是地的接缝,不是地的本体。分清这一层,后面的字段、层级、面积口径才有意义。
| 项目 | 数值 | 依据 |
|---|---|---|
| 层级 | 12 级(lev01 至 lev12) | 产品页与技术文档 |
| 最细一级多边形 | 512,736 个 | 九个洲 lev12 图层 dbf 记录数合计 |
| 一级多边形 | 5 个(非洲 1、亚洲 1、澳洲 1,南美 1、欧亚合 1) | lev01 各洲记录数 |
| 属性列 | 13 列(标准格式) | lev12 图层 dbf 头部字段表 |
| 最细一级平均面积 | 130.6 平方公里 | 产品页原文 |
| 覆盖陆地 | 1.35 亿平方公里(不含南极) | 产品页原文 |
| 分级阈值 | 支流上游面积 100 平方公里 | 产品页与技术文档 |
| 强制细分线 | 超过 250 平方公里必拆 | 技术文档 2.1 节 |
| 底图分辨率 | 15 弧秒,赤道约 500 米 | 技术文档第 2 节 |
| 拼接包 | 9 个洲包,46 至 524 MB | 官方下载链接的文件大小 |
| 许可 | 自定义 HydroSHEDS 许可,允许商用 | 产品页许可段落 |
| 主引用 | 10.1002/hyp.9740 | 产品页参考文献 |
§1 速览:它是什么,也不是什么
1.1 一句话定义
HydroBASINS 是一套全球子流域边界的多边形矢量库,以 HydroSHEDS 核心层的十五弧秒流向栅格为底,按统一的面积门槛切分,再用 Pfafstetter 十进制编码把切出来的碎块组织成十二级嵌套。
它的定位可以这样说:把「地表的水往哪流、流到哪块地为止」这件事,做成一张可以按任意颗粒度聚合、可以顺着下游一直走到海的矢量底图。
1.2 三层身份
第一层是几何。两百多万个多边形(十二个层级合计一百八十八万个,最细一级五十余万个),WGS84 经纬度,没有投影。这意味着面积不能从几何直接算,必须读 SUB_AREA 列。
第二层是编码。每个多边形带一个 Pfafstetter 码,位数等于它的层级。这个码不是随机编号,而是一份祖先链:前 N 位相同的多边形,在一级一级往上汇总时会被合并成同一个父多边形。
第三层是拓扑。每个多边形都记着自己的下一个下游是谁。把这列当成边,整张表就是一张有向无环图,图的汇集点在海边或内流盆地的最低处。
三层身份里,最容易被浪费的是第二层。多数人只把 PFAF_ID 当作一列可以忽略的编号,用它算面积,然后在需要按「某条大河的整个流域」聚合时,转去空间相交。实际上,六位前缀相同就是同一个层级六的父流域,不需要任何几何运算。
1.3 三十秒决策卡
| 你的处境 | 它能给你什么 | 你要自己补什么 |
|---|---|---|
| 要把点状观测按流域汇总 | 十二级现成的汇水边界,选一层相交即可 | 哪一层合适,得看观测密度 |
| 要做上游下游溯源 | NEXT_DOWN 一列就走完整条链 | 内流区的虚拟连接要先判掉 |
| 要算某条河的集水面积 | UP_AREA 直接给出结果 | 大河口的值受海岸聚合单元影响 |
| 要按行政单元报数 | 与国界做空间相交即可 | 国界本身要用另一份数据 |
| 要做流域出口分析 | ENDO 能标出没有出海口的那一类 | 海里的出口要再叠一层海岸线判断 |
| 要研究流域边界的十年变化 | 无。只有一版 | 整个时间序列,得换方法重做 |
| 要降水、温度、土地利用 | 无。十三列全是几何与拓扑量 | 全部要外部挂接 |
1.4 不适合谁
不适合拿它做流域边界变化分析的人。整套数据只有一个时相,源自 2000 年前后的高程快照。想回答「这个流域的集水范围二十年间有没有变」,这份数据给不了第二个时相。
不适合需要单条河道形态的人。它画的是面,河是面的接缝。河道的宽度、弯曲、比降,全都不在里面,那要去 HydroRIVERS。
不适合要精确到小支流的人。一百平方公里是分级门槛,低于这个面积的支流在最高细分层级里不会成为独立单元,而是被并进相邻的间流域。一个五十平方公里的支流流域,在这套数据里没有名字,只有它所在的那个多边形。
不适合把十二个层级当成十二份样本的人。它们不是十二份数据,是同一份数据在十二个分辨率上的读数。混着用会重复计数,后面 §4 有一整节讲这件事。
1.5 贯穿本文的案例:那两条面积凑不齐的邻居记录
打开欧洲的 lev12 图层,前三条记录就足够把整套数据的性质说清楚。
第一条是 2120000010:SUB_AREA 5.1 平方公里,UP_AREA 也是 5.1,COAST 标着 1,ORDER 是 0,NEXT_DOWN 是 0。这是一块被合并的海岸流域,面积小得像个点,自己就是自己的出口。
第二条是 2120000020:SUB_AREA 157.7 平方公里,UP_AREA 6,264.1 平方公里,ORDER 是 1,COAST 是 0,NEXT_DOWN 是 0。这是一块流域的出口单元,自己占 157.7 平方公里,收下来的全部汇水面积是 6,264.1 平方公里,四十倍的差距。
第三条是 2121297490:SUB_AREA 188.5 平方公里,UP_AREA 6,106.4 平方公里,NEXT_DOWN 指向 2120000020。这个多边形的 PFAF_ID 是 211012010120,十二位,说明它在第十二级。PFAF_ID 每四位一组往回读:前六位 211012 是它所在的六级单元,前十二位就是它自己。
现在把三个数摆在一起。出口那块 157.7,加上 188.5,是 346.2;可出口的 UP_AREA 是 6,264.1。差了 5,900 多平方公里,说明出口的汇水范围里还有别的单元,只是它们写在别的行里,不在这三条之中。
再补一处细节。2121297490 的直接上游有两块:2120819900 是 134.8 平方公里,2120820060 是 19.7 平方公里,两者加起来 154.5。加上它自己的 188.5,得 343.0。而它那一行的 UP_AREA 写着 6,106.4,是 343 的十八倍。缺口全在第二块上游身上——它的 UP_AREA 是 5,783.2,也就是说它脚下还压着一大片上游。
这件事就是本文要说的一切的起点:同一行里的两个面积不是一回事,不同行之间的面积不能凭直觉相加,而一棵完整的树要顺着指针才能拼出来。
再补一层:这两块的 PFAF_ID 是 211012010200 与 211012010300,末两位不同,一个 2 一个 3。按 Pfafstetter 的读法,2 是支流、3 是间流域——同样是它的上游,一块是河来的水,一块是两河之间的地。
这个案例会在后面反复出现。它的用处是:只要盯住这几行,很多常见误解会在几秒钟内自己露馅。
§2 数据构成:全球被切了十二遍,为什么是十二遍
2.1 两个图层,九个包
产品以九个洲包发布,每个洲包内含该洲的十二个层级加一个层级零图层,全部是 ESRI shapefile。文件名有固定语法:hybas_XX_levYY_v1c.shp,XX 是洲代码,YY 是层级号。
九个洲的代码分别是 af 非洲、ar 北美北极、as 亚洲、au 澳大利亚与大洋洲、eu 欧洲与中东、gr 格陵兰、na 北美与加勒比、sa 南美、si 西伯利亚。
这个打包方式有一个不显眼但很重要的后果:层级不是跨洲对齐的。非洲的 lev06 有一千二百多个多边形,格陵兰的 lev06 只有三百来个。想凑齐全球某一层,必须把九个洲的那一层拼起来,然后接受不同大洲在这同一层上的颗粒度差异巨大。
九个包的体积从 46 MB 到 524 MB,最大的是非洲。非洲之所以最大,一半是因为面积,一半是因为它同时包含了面积最大的一级单元(整个非洲大陆是 lev01 的一条记录)和层次结构最深的流域。
2.2 分叉规则:两条支流各自一百平方公里
切分规则写在产品页第一段,也写在技术文档第二节:在任何一个汇流点上,如果汇进来的两条支流各自的上游面积都达到 100 平方公里,就在这里把流域一分为二。
这条规则足够简单,但会产生两种明显的副作用,技术文档自己点了出来。
第一种是间流域可以任意小。两条支流之间的那块地,不流入任何一条支流,面积不受门槛约束,可以是几平方公里,也可以更小。所以在属性表里看到比 100 小得多的 SUB_AREA,不是错误。
第二种是子流域可以任意大。如果一条主干流长距离没有够格的支流汇入,它所在的那个单元会一路累积,可以远超 100 平方公里。
为提高一致性,团队加了一条强制规则:凡是超过 250 平方公里的子流域,沿主干流插入额外断点,强行拆分。这条 250 平方公里的线,在产品页上找不到,只在技术文档第二节的正文里有一句。
2.3 十二级是怎么来的
Pfafstetter 编码的基本动作是:一个父单元,按支流大小排序,取最大的四条支流编偶数(2、4、6、8),再把夹在它们之间的五块间流域编奇数(1、3、5、7、9)。每往下走一级,就在编码末尾追加一位。
这套规则天然是九进制的,理论上可以无限往下走。那为什么停在十二级?原因不在编码,在数据。层级越深,每个单元越小,而底图是十五弧秒的栅格,赤道处一格约五百米,面积约 0.25 平方公里。切到某个深度之后,一个多边形只剩几个像元,再切下去就是在切栅格的噪声。
实际数据里有一条更清楚的信号:十一级到十二级几乎不再增长。非洲从 229,572 条到 230,028 条,只多了 456 条;北美从 122,028 条到 122,251 条,多了 223 条;格陵兰从 16,968 条到 16,990 条,多了 22 条。
也就是说,第十二级这一整层,只比第十一级多出不到千分之一的多边形。第十二级名义上存在,实际上绝大部分单元在第十一级已经停止细分。这个现象对使用者有直接影响:需要最高分辨率时,选十一级还是十二级,结果几乎一样,但十二级的文件要大一些。
2.4 九个洲与一条人工的线
前三级 Pfafstetter 编码是人工指的,不是算法生成的。
一级对应九个大洲,编码是固定的:1 非洲、2 欧洲、3 西伯利亚、4 亚洲、5 澳大利亚、6 南美、7 北美、8 北美北极、9 格陵兰。
二级把每个大洲拆成最多九个单元。三级开始,各大洲最大的河流盆地开始分离出来。
从四级起,回到传统的 Pfafstetter 规则。这个交接点很重要:前三级的语义与四级以后完全不同。一级是地理分区,不是水文单元;到了四级,才是真正按支流的相对大小排序。
技术文档还交代了播种顺序:一级编码从非洲大陆东北角起,沿各大洲海岸逆时针推进(欧洲、西伯利亚、亚洲,再到澳大利亚与美洲),岛屿就近插入序列。
2.5 三处规则之外的人工处理
原始 Pfafstetter 方案是为一国之内的流域设计的一套体系,搬到全球会撞上三类它没有考虑过的东西。技术文档用专门段落处理了这三类。
岛屿。原始方案没有为岛屿设计嵌套编码。数据里按人工分组处理,例如一级上新西兰属于澳大利亚这一块,二级上新西兰南北两岛合成一个单元,三级上两岛分开。
内流区。原文写得很直白:内流盆地,也就是不流入海洋的内陆汇,在 Pfafstetter 方案里没有对应规则。处理办法是人工分组、人工赋初始编码,低层级时先做成聚合组,高层级时才拆出单个内流盆地;一旦某个内流盆地被单独拎出,就回到标准规则继续细分。
小块海岸流域。夹在两条大河之间、径直入海的小流域,如果不处理会产生数量极多的微小单元,编码还会继续把它们越切越碎。数据里把它们合并成海岸排水单元,允许的最大单个面积是 500 平方公里,60 度北纬以北的低质量区放宽到 700 平方公里。这类单元在属性表里由 COAST 等于 1 标出,河序一律为 0。
2.6 跳级与那个 0
传统 Pfafstetter 要求每一级都必须严谨地拆成九份。技术文档承认这会导致同一层的单元大小极不均匀:四条大支流可能形成四个大单元,五块间流域可能小得多,下一级再各拆九份,差异会一路传递甚至放大。
数据里加了一条自动规则:按层级设定面积容差,低于容差的单元在下一级跳过细分,跳过的位置在编码里填 0。
这就解释了一个初次使用时会困惑的现象:层级十二的 PFAF_ID 明明是十二位,末位却有大量是 0。以欧洲的最细一级为例,十二位编码末位为 0 的约占九成九。换句话说,十二位编码里,绝大多数单元的真实深度不到十二级。
那个 0 不是占位符,也不是缺失值,它是一句明确的陈述:这里没有继续细分。
2.7 带湖版本是另一份产品
除了标准格式,官方还发了一套「带湖」版本,文件名多一段 lake。它的来历写在技术文档里:为 BioFresh 项目的特殊需求制作,与 IUCN 合作完成,把 GLWD 全球湖泊湿地库的湖面多边形裁剪进子流域。
这套版本引入的问题,技术文档自己列了很长一段。湖面可能横跨来自不同支流的多个子流域,把它们连起来;人工水库可能把原本独立的流域连通;潟湖可能伸进海里甚至串起相邻流域。结论是:在这类特殊情形下,严格的上下游拓扑不一定成立,连通性可能不一致,或者在特定组合下被主动切断以避免搜索算法死循环。
还有两处结构上的改动。一是湖按其面积从某个层级开始才出现:不小于 1000 平方公里的湖从四级起,不小于 250 的从五级起,不小于 10 的从八级起,不小于 2 的从十一级起。二是当一个湖覆盖子流域出口时,子流域沿主干流被劈成左右两半,用 Side 字段区分,并在 HYBAS_ID 末位体现。
选择哪一套,答案取决于用途。要拓扑干净、要按编码聚合,用标准格式;要对湖泊做研究,用带湖版本,同时接受它的连通性是有条件成立的。
§3 结构层:Pfafstetter 编码怎么读
3.1 Pfafstetter 的原型:九份,偶数支流,奇数间流域
理解这份数据的关键只有一条规则,其余都是它的推论。
假设有一块流域,里面最大的支流按面积排前四位。Pfafstetter 的做法是:把这四条支流各自的汇水区编成 2、4、6、8,再从最下游往上游,把它们之间的五块地编成 1、3、5、7、9。于是这块流域被切成九份,编码是 1 到 9。
下一位的含义随之确定。一个编码是 24 的单元,意思不是「第二十四块」,而是「父单元里第二条支流,在它内部又是第四条支流」。
这套规则的好处有两个。第一,编号本身携带拓扑信息:偶数代表真支流,奇数代表间流域,一眼能看出这个单元是「一条河的地」还是「两条河之间的地」。第二,前缀即祖先:所有前两位相同的单元,两级之后必然合并成同一个父单元。
对照数据,这条性质是成立的。欧洲最细一级里,取前五位不同的有 674 个,恰好等于欧洲 lev05 的 674 条记录;取前六位不同的有 2,240 个,恰好等于 lev06 的 2,240 条;前四位 240 个,等于 lev04 的 240 条。三个层级三处对得上,说明前缀聚合是真的能替代空间运算的。
3.2 一个真实的编码,逐位读一遍
拿 §1.5 的案例,那串编码是 211012010120。
第一位 2:欧洲。
第二位 1:欧洲内部第一个二级单元。
第三位 1:三级单元里的第一个。
第四位 0:这一级跳过了,不细分。
第五位 1:继续往下,第一个间流域。
第六位 2:这一块里的第二条支流。
第七位 0:跳过。
第八位 1:间流域。
第九位 0:跳过。
第十位 1:间流域。
第十一位 2:第二条支流。
第十二位 0:跳过。
逐个读下来,一串十二位的编码其实只有五个有效位:2、1、1、1、2、……中间夹着六个 0。这些 0 的位置说明了一个具体事实:这条支流在十二个层级里只真正经历了六级细分,而不是十二级。
这就是为什么不能把 PFAF_ID 当数字比较大小。字符串比较也不行——长度相同的两个码,有效位数量可能差好几个。
3.3 HYBAS_ID 是十位,与 PFAF_ID 分工不同
属性表里同时有两个编码,用途不一样,混起来很常见。
HYBAS_ID 固定十位,结构是「一位大洲 + 两位层级 + 六位序号 + 一位左右侧」。以 2121297490 为例:2 是欧洲,12 是层级十二,129749 是网络内序号,末位 0 表示无侧别。
PFAF_ID 是变长的,位数等于层级,结构是纯粹的 Pfafstetter 码。
两者的分工:HYBAS_ID 用来做唯一的行标识与跨表连接,PFAF_ID 用来做层级聚合。要按某条大河的整个流域分组,用 PFAF_ID 的前缀;要把这张表和别的数据挂接,用 HYBAS_ID。
数据里对上了两件事。其一是 HYBAS_ID 首位与 PFAF_ID 首位永远相同,欧洲 lev06 的 2,240 条记录全部满足。其二是 HYBAS_ID 第 2 位到第 3 位恒等于当前层级号,同样是全表满足。
还有一个细节值得记:末位那个侧别标记,在标准格式里恒为 0。以欧洲的最细一级为例,末位是 0 的记录占了全部,一条不差。只有带湖版本才会出现 1 与 2。
3.4 层级是十二份独立数据,不是一张表加一列
这一点必须说透,因为它决定了所有下载与加载的做法。
官方的发布方式是:每个洲,每个层级,一个独立的 shapefile。九个洲乘以十二个层级,加上九个层级零图层,一共一百一十七个文件。它们可以按洲打包下载(九个压缩包),也可以按层级单独下载。
这意味着同一个物理地点,在数据里出现十二次,每次是一个不同大小的多边形,带一个不同的 HYBAS_ID,但 PFAF_ID 有相同的开头。
各层的规模差了几个数量级。全球合计的数字是:
| 层级 | 全球多边形数 | 约数 |
|---|---|---|
| lev01 | 5 | 个位 |
| lev02 | 31 | 几十 |
| lev03 | 132 | 百 |
| lev04 | 681 | 千 |
| lev05 | 2,297 | 千 |
| lev06 | 8,037 | 万 |
| lev07 | 29,118 | 万 |
| lev08 | 96,286 | 十万 |
| lev09 | 254,929 | 十万 |
| lev10 | 467,016 | 十万 |
| lev11 | 511,632 | 五十万 |
| lev12 | 512,736 | 五十万 |
十二个层级合计 1,882,900 条记录。这个数与官方那个「一百万个多边形」不是一个口径:官方的一百万指最细一级的全球数量,这里的五十余万是逐洲相加的结果,差额来自官方那句粗略表述与真正的最细一级计数之间的分别。
3.5 选错层级会丢掉上下游关系
层级的用途不是「越细越好」,而是「与研究尺度匹配」。
在三级上做溯源,得到的是一条大河的骨架:源头、干流、入海口,中间几乎没有细节。在十二级上做溯源,得到的是一条完整的支流网,节点数可能是三级的一万倍,下游遍历的计算量也是。
真正容易出问题的是反向的错配:用太粗的层级去回答细的问题。
假设要研究某条支流的泥沙输移,这条支流在十二级里是 4,000 个独立单元,在六级里可能只剩二十来个。如果用六级做,上游到下游的关系会大量丢失——不是边少了,是节点被合并了,原本属于两个不同单元的输入被压进同一行。
反过来也有一类错配:用太细的层级做区域汇总。每个行政单元在十二级里平均要叠几十个多边形,做加权平均时权重怎么给,会直接影响结果。
一个经验判据是:让平均多边形面积与研究单元的典型面积同一个数量级。研究一个县的农业面源污染,县的面积在几千平方公里这个量级,选七级或八级比较合适;研究一个大陆的水资源总量,选二级或三级。
3.6 SUB_AREA 与 UP_AREA:两个面积,两种含义
这是属性表里最容易搞混的一对列,也是 §1.5 的案例之所以成立的原因。
SUB_AREA 是本多边形的面积,几千到几百平方公里。用技术文档的原话,就是「单个多边形的面积」。
UP_AREA 是从源头算到这个多边形出口的累计汇水面积,包含本多边形自身。技术文档还补了一句限制:只统计地表直接连通的面积,不包括那些通过虚拟连接并入同一个大流域的内流区。
还是 §1.5 的案例,2121297490 这一行:SUB_AREA 是 188.5,UP_AREA 是 6,106.4。前者是这块中游坡地自己的面积,后者是从源头一路汇下来的全部面积。
用哪个?这取决于问题问的是什么。
问「这块地有多少面积」,用 SUB_AREA。
问「这个出口控制多大范围」,用 UP_AREA。
问「这个流域的径流系数是多少」,用 UP_AREA 做分母。
问「这个单元的本地产流是多少」,用 SUB_AREA。
数据里这条关系是守恒的:全表没有任何一条 UP_AREA 小于 SUB_AREA。全表检查下来,违反的为零。这是一次有效的自检——如果看到 UP_AREA 比 SUB_AREA 小,那一定是读错了列或者连错了表。
3.7 ENDO:内流区的三态
内流区是没有地表出口的汇水区,水最终蒸发或下渗,不流入海洋。里海、咸海、塔里木盆地都属于这一类。
ENDO 字段有三个取值。
0 表示不属于内流区,这是全表的大多数。欧洲 lev12 里有 99,714 条。
1 表示属于内流区,但不是汇点,也就是这块地在水流向内流盆地汇的过程中。欧洲 lev12 里 35,118 条。
2 表示是内流区的汇点,也就是最下游那一块。欧洲 lev12 里 2,826 条。
做流域出口分析时,ENDO 等于 2 的这一类必须单独处理。它们不是出海口的流域,用它们算「入海通量」会得出错误结论。
但 ENDO 的设计比一个简单标记更精细,下一节的虚拟连接就是在这个字段上做的。
3.8 NEXT_DOWN:一列字段就是一张有向图
把 NEXT_DOWN 当边,HYBAS_ID 当点,属性表就是一张有向图。每条记录最多指向一个下游,也可能谁也不指。
以欧洲 lev12 为例。全表里 NEXT_DOWN 为 0 的有 10,443 条,其余 127,215 条都有明确的下游。没有自环,也没有指向本表之外的悬空引用——127,215 条外部指针全部能在同一张表里找到落点。这三点合起来说明这张图是闭合的、无环的、可遍历的。
这就是为什么说它是「河网溯源的基础」。从任意一个多边形出发,反复读 NEXT_DOWN,一定会在有限步内到达一个 0,而那个 0 就是在海边或内流盆地最低处。
图的方向是单向的。从下游往上游走,得反过来用:先按 NEXT_DOWN 建一张反向索引,再执行广度优先搜索。这在数据里没有现成的列,要自己做。
3.9 NEXT_SINK 与 MAIN_BAS:两个「最终去哪」
两个字段都在回答「最终流到哪里」,口径不同。
NEXT_SINK 给的是「下一个下游终端水体」。如果下游路上先遇到内流汇,填那个内流汇的 HYBAS_ID;如果没有内流汇,才填整个流域最下游的多边形。技术文档的说法是,这一列用来识别「完全连通的流域」,即从这块地出发真正能连到底的那一片。
MAIN_BAS 给的是主干流域出口,即最下游那个多边形。技术文档的说法是,用它可以把大流域连同周边的小内流区一起归到同一个流域。
两个字段的差别就是「视虚拟连接为断开还是视为连通」。做水量平衡,用 NEXT_SINK;做行政或区域汇总,用 MAIN_BAS。
3.10 DIST_SINK 与 DIST_MAIN:距离的两种算法
DIST_SINK 是沿河网到下一个下游终端水体的距离,单位公里。DIST_MAIN 是沿河网到主干流域出口的距离。
这里有一个关键的口径说明,写在技术文档里:当小内流区并入大流域时,虚拟连接不按真实绕行距离计算,而是算作直接相连,距离记零。
后果是:在虚拟连接附近,DIST_SINK 与 DIST_MAIN 会出现突然相等的情况。这不是数据错误,是算法在明确告诉你「这里是一条虚拟边」。看到这种相等,就该回去查那一行的 ENDO。
3.11 COAST 与 ORDER:海岸聚合单元的标记
COAST 等于 1 的多边形是合并后的海岸流域,由若干条流入海的小流域组成。欧洲 lev12 里 4,775 条。
ORDER 是河序,从出口往源头编号:1 是主干,2 是汇入主干的支流,依此类推。欧洲 lev12 的分布是:0 的 4,775 条,1 的 25,546 条,2 的 40,669 条,3 的 37,144 条,4 的 20,610 条,5 的 6,969 条,6 的 1,637 条,7 的 272 条,8 的 32 条,9 的 3 条,10 的 1 条。
两个字段是联动的:ORDER 为 0 的条数与 COAST 为 1 的条数完全相等,一条不多一条不少。这说明海岸聚合单元在河序体系里被明确排除在外,不是因为它们不重要,而是因为它们没有单一的河道可以编号。
3.12 SORT:一个容易被忽略的字段
SORT 是原始 shapefile 的记录流水号。技术文档说明,原始多边形按从下游向上游排列。
这个字段的价值在于复现。做拓扑搜索时,如果按 SORT 的顺序处理,很多算法可以一次遍历就得到稳定的结果,不需要反复迭代。数据里 SORT 与记录顺序完全一致,欧洲 lev12 的第一条 SORT 是 1,第二条是 2,依此类推。
它还是一把对账的尺子。把文件读进数据库后,要确认行序没有被打乱,比一下 SORT 的首末两值就知道。
§4 层级与嵌套:为什么把两层混在一起算面积会翻好几倍
4.1 嵌套的定义:上一层恰好等于下一层的并集
嵌套不是近似的说法,是可以被数据验证的等式。
把欧洲十二个层级的 SUB_AREA 全部加起来,分别得到:一级 17,858,904,二级 17,858,903.9,三级 17,858,904,四级 17,858,903.6,五级 17,858,903.9,六级 17,858,902.4,十二级 17,858,911.4。
六个层级、一个量级、差异在十平方公里以内,也就是千分之零点五。这不是巧合,这是嵌套的直接证据:无论在多深的层级上汇总,最后得到的都是同一块地。
北美也一样。十二个层级逐一汇总,一级 15,914,618,六级 15,914,618,十级 15,914,612,十二级 15,914,616。最大差值是十平方公里,相对误差不到百万分之一。
结论很硬:十二个层级描述的是同一块地,一层不差。
4.2 重复计数的机制
既然十二层覆盖的是同一块地,那么把两层或多层的面积加在一起,得到的就是若干块地的叠加,数字会按层数放大。
两块地加起来是两倍,十二块加起来是十二倍。这不是估算,是算术。
实践中更常见的形式没那么明显:某人加载了 lev06 与 lev10 两个图层,做空间相交后按行政区汇总面积。因为两个图层在同一块地上都覆盖完整,相交结果会把每个区域算两遍。看到面积翻倍时,第一反应往往是投影或坐标单位错了,实际上可能只是叠了两层。
还有一种隐蔽的形式:把不同洲的不同层级拼到一起。非洲用 lev06,欧洲用 lev08,拼成一张「全球流域图」。这在视觉上是一张完整的地图,在使用上是一个混合颗粒度的对象,任何按多边形计数的统计都会偏向欧洲。
4.3 层级零:唯一一个「一张表全包含」的图层
技术文档说明,标准格式额外提供一个层级零图层,包含最细一级的全部多边形,属性表里带齐 pfaf_1 到 pfaf_12 十二列编码。用户可以从这一层出发,按任意层级的目标编码做溶解,得到该层级。
这个设计的意义是:如果你需要多层级一起用,原则上应该只加载层级零,然后在同一个表里按不同列溶解。这样不会丢行,也不会重复计数。
数据里验证了这一点。格陵兰的层级零有 16,995 条,格陵兰的 lev12 有 16,990 条。差距五条,原因不是漏画,而是编码重复:层级零里有 4 组 Pfafstetter 码出现了两次,也就是说有两对相邻多边形被赋了相同的十二位编码。所以在层级零上按 pfaf_12 溶解,得到的单元数会比 lev12 少两条。
这五条差额是一个很具体的提醒:层级零与 lev12 不是同一份东西的两种排列。前者是原始多边形,后者是重算过的发布图层。做严格对账时,要用前者。
4.4 跨层级 join 的三种写法
要把某块地和它在别层的对应单元连起来,有三种做法,可靠性与成本依次不同。
第一种是前缀匹配。最便宜,不用几何。取 PFAF_ID 的前 N 位,去和 levN 的 PFAF_ID 相等匹配。欧洲数据验证过:十二级里取前五位不同的有 674 个,正好是五级的 674 条记录。这条路成立的前提是两边的 PFAF_ID 编码一致。
第二种是空间相交。最贵,但最通用。把细层的多边形和粗层做空间包含,得到映射。这条路不依赖编码的正确性,可以跨格式、跨版本用。
第三种是用层级零的 pfaf_N 列自关联。最省事,前提是你只用层级零。
三者的结果在同一份数据上应当一致。如果不一致,最可能的原因是编码里的跳过位没有处理好——按前缀匹配时,一个前缀里含有 0 的单元,它的真实层级比前缀长度浅。
4.5 层级选择的三条经验线
第一条是面积匹配。让平均多边形面积与研究单元同量级。
第二条是观测密度匹配。有多少个观测点,就选能让每个多边形平均摊到一两个点的那一层。点太稀,多边形就要粗。
第三条是拓扑需求匹配。要做完整的上下游溯源,层级不能太粗;只做区内汇总,层级可以粗。
三条线冲突时,取最细的那一条对应的层级。粗的可以随时往上溶解,细的没法往下拆。
4.6 那个「十二级几乎不再增长」的实际后果
前面提过,十一级到十二级全球只增加了 1,104 个多边形。
对使用者的含义有三点。
第一,最高精度的边际收益很小。选十一级,能省下约 15% 的文件体积与解析时间,代价是极少数位置少一层细节。
第二,官方的「十二级」是一个名义上限,不是一个均匀的细分深度。更深处的细分被面积容差规则挡掉了,被挡住的位置编码填 0。
第三,任何声称「十二级有三十亿个单元」的说法都不成立。真实的十二级是五十余万个。
4.7 嵌套不等于对齐
最后一点要说清:嵌套是逻辑关系,不是几何对齐。
上一层的多边形等于下一层若干多边形的并集,这句话在逻辑上成立,但这并不意味着上一层的边界线在几何上与下一层的边界线逐段重合。因为栅格化、简化、溶解的顺序不同,两个层级在某一段边界上可能出现几十米的错位。
实践中这意味着:按前缀匹配得到的父单元,其几何是父层自己画的;用下一层溶解得到的父单元,其几何是下一层合并出来的。两者画在一起会有细缝。做严格的面积核对时,要用 SUB_AREA 列,不要用几何现算。
§5 拓扑层:NEXT_DOWN 与那张图
5.1 图的规模
欧洲 lev12 那张图的规模可以量出来。
节点 137,658 个。边 127,215 条(NEXT_DOWN 不为 0 的记录数)。入度为 0 的节点 10,443 个,也就是出口。平均每条边指向一个节点,没有节点接收超过一条下游指针——这是「每个多边形只有一个下游」的直接体现。
出度可以任意大。一条主干流上的多边形,可能接收几十条支流。
图的深度可以从 DIST_MAIN 的最大值看出来。欧洲 lev12 的 DIST_MAIN 最大值是 3,813.8 公里,这意味着从最远的源头沿河网走到出口,要走将近四千公里。欧洲没有这么长的河,这个值多半对应一条从俄罗斯西北部流到里海的路径,中间经过了虚拟连接。
5.2 出口有三种,别只认一种
NEXT_DOWN 等于 0 的节点,看起来都是出口,实际上分三类。
第一类是海出口。ENDO 是 0,COAST 可能是 0 也可能 1。欧洲 lev12 里,这类有 8,549 条。
第二类是内流汇点。ENDO 是 2。欧洲 lev12 里 1,894 条,例如 2120085500,SUB_AREA 98.4,UP_AREA 281,499.6,NEXT_SINK 是自己。
第三类是内流区的虚拟连接端。这一类的 ENDO 是 2,但 NEXT_DOWN 不为 0,所以不在「出口」里。下一节专门讲。
只认 NEXT_DOWN 等于 0,会把第二类当成海出口,也会漏掉第三类的特殊性。
5.3 虚拟连接:一条标注过的假边
技术文档花了整整一段讲这件事,值得原样理解。
很多大河流域内部夹着小内流盆地。尼罗河流域中部就有不少这类小盆地,它们与主河道没有地表水流相连,但在地理与地下水层面通常被视为同一个流域的一部分。
为了保留这层归属,又不破坏拓扑查询,数据给一部分内流汇点设了「虚拟」连接,指向一个恰当的下游多边形。
数据里怎么认出来:ENDO 等于 2 且 NEXT_DOWN 大于 0。两个条件同时成立才是虚拟连接。
欧洲 lev12 里,ENDO 为 2 的记录共 2,826 条。其中 NEXT_DOWN 为 0 的是 1,894 条(真实内流汇),NEXT_DOWN 大于 0 的是 932 条(虚拟连接)。
这 932 条就是那颗钉子。从它们出发继续沿 NEXT_DOWN 走,会走到下游多边形,但那一段路在地表上并不存在水流。做水量平衡时,如果不在这些节点上断开,把假的汇集当成真的,算出来的入海量会偏大。
技术文档给了使用者一个选择权:路由可以在内流汇终止,也可以穿过。这是设计上的留口子,不是疏漏。
5.4 从任意点到海的四种走法
给一个 HYBAS_ID,想走到海,有四种做法,结果不同。
走法一:只按 NEXT_DOWN。最简单,但会把虚拟连接当成真连接。适合做区域汇总,不适合做水量平衡。
走法二:按 NEXT_DOWN,但遇到 ENDO 等于 2 且 NEXT_DOWN 不为 0 就停下。这是严格的地表路由。
走法三:按 NEXT_SINK 直接跳到下一终端。一步到位,适合只需要「最终归哪个水体」的场景。
走法四:按 MAIN_BAS 分组。不做路径,只做归属。
数据里对走法二做过验证:因为 ENDO 等于 2 的节点不会再有 1 类型的下游,停下来之后得到的就是一个真正的内流盆地。
5.5 反向下溯:从海往上找支流
反方向没有现成的列,要自己建反向索引。
做法很简单:按 NEXT_DOWN 分组,得到每个节点的上游子节点列表,然后从出口做广度优先搜索。
有一条经验可以省很多时间:如果只需要某一层的上游,不要从出口往下搜,而是用 PFAF_ID 前缀过滤。取出口的 PFAF_ID 前 N 位,找所有同前缀的单元,就是它的上游范围。这比图搜索快好几个数量级。
5.6 UP_AREA 是自洽的,但不等于加总所有上游
一个容易产生的预期是:一个多边形的 UP_AREA,应当等于它自己的 SUB_AREA 加上所有上游多边形的 SUB_AREA 之和。
这个预期大体成立,但有两处偏差。
第一处是虚拟连接。技术文档明确写:UP_AREA 只包括直接连通的面积,不包括通过虚拟连接并入的内流区。所以一个小内流区虽然在 MAIN_BAS 上与大树归在一起,它的面积不计入下游的 UP_AREA。
第二处是边界截断。UP_AREA 从源头算起,而源头在数据里是以该层级的第一个多边形为界。研究区如果被裁剪过,上游的 UP_AREA 仍然反映的是全球范围内的完整汇水,而不是裁剪后的。
§1.5 的案例可以做一次手算校验。2121297490 的 UP_AREA 6,106.4 减去 SUB_AREA 188.5,得 5,917.9,这是它应当收到的上游水量面积。但它的两块直接上游,SUB_AREA 加起来只有 154.5,UP_AREA 加起来是 5,917.9。后者对上了,前者差得很远。
这个差值的解释就是 UP_AREA 的定义:它不是把上游邻居的 SUB_AREA 加起来,而是把上游邻居的 UP_AREA 加起来。一块小地可以扛着一大片上游,加总时必须用后一列。
5.7 用 SQL 做一次溯源
数据能直接读进任何支持 dbf 的数据库,下面是一段可运行的 SQL。
-- 读入后建表,HYBAS_ID 与 NEXT_DOWN 都存成整数,避免字符串比较
CREATE TABLE hb12 (
hybas_id BIGINT PRIMARY KEY,
next_down BIGINT,
next_sink BIGINT,
main_bas BIGINT,
dist_sink REAL,
dist_main REAL,
sub_area REAL,
up_area REAL,
pfaf_id BIGINT,
endo INTEGER,
coast INTEGER,
ord INTEGER,
sort INTEGER
);
-- 严格地表路由:从某个点出发,只沿 NEXT_DOWN 走,
-- 遇到虚拟连接(endo=2 且 next_down<>0)即停
WITH RECURSIVE route AS (
SELECT hybas_id, next_down, endo, 1 AS step
FROM hb12 WHERE hybas_id = 2121297490
UNION ALL
SELECT h.hybas_id, h.next_down, h.endo, r.step + 1
FROM hb12 h
JOIN route r ON h.hybas_id = r.next_down
WHERE r.next_down <> 0
AND NOT (r.endo = 2 AND r.next_down <> 0)
)
SELECT * FROM route ORDER BY step;
这段跑完,会得到一条长度有限的路径,最后一步的 next_down 就是出口,或者是一个虚拟连接点。
第二条查询做归属统计,把同一主干流域的全部单元归到一起:
-- 按主干流域出口分组,看每个主干流域控制多少子流域与多少面积
SELECT main_bas,
COUNT(*) AS n_sub,
ROUND(SUM(sub_area)) AS sum_sub_area,
ROUND(MAX(up_area)) AS max_up_area
FROM hb12
GROUP BY main_bas
ORDER BY sum_sub_area DESC
LIMIT 20;
分组的顺序大致能反映主干流域的规模,但要记住:sum_sub_area 是各子流域面积之和,max_up_area 是控制范围内最大的累计汇水面积。两个数不相等,因为它们回答的不是同一个问题。
第三条查询找内流区:
-- 内流盆地的汇点:endo=2 且 next_down=0
SELECT hybas_id, sub_area, up_area, pfaf_id, dist_main
FROM hb12
WHERE endo = 2 AND next_down = 0
ORDER BY up_area DESC;
结果里的面积排序,就是内流盆地的大小排序。
5.8 一层套一层的遍历代价
在十二级上做全图遍历,节点数五十多万。用递归 CTE 从每个出口开始走,是可行的,但要注意两点。
一是递归深度。欧洲最长路径约四千公里,如果按平均多边形尺寸折算,深度可能在几十到上百层之间。默认的递归层数限制可能需要调大。
二是索引。NEXT_DOWN 必须有索引,否则每一次并集都要全表扫描。
§6 规模层:数字到底多大,边界在哪里
6.1 那个「一百万个多边形」
产品页原文写的是:在最细一级的细分上,HydroBASINS 包含一百万个独立子流域多边形,平均面积 130.6 平方公里,覆盖全球陆地 1.35 亿平方公里,不含南极。
逐洲统计得到的实际值是 512,736。这两个数字有差距,差距大约一倍。
怎么解释?官方说的「一百万个」是一个措辞上的数量级,为的是给人一个直观规模感,不是逐条数出来的精确计数。真正的最细一级在五十万左右。
这组数字之间的关系也能自洽:1.35 亿除以 51.3 万,约等于 263 平方公里,与官方那个 130.6 差一倍。而 1.35 亿除以 103 万,才等于 130.6。所以官方那一百万这个数,如果与平均面积配套,推出来的应该是另一套切分。
这个落差不是一个需要争辩的问题,而是一个使用提醒:遇到一个「多少个多边形」的数字时,要问它是哪一级、哪个口径。
6.2 覆盖的边界:南极不在里面
1.35 亿平方公里是官方给的陆地覆盖,明确不含南极。全球陆地面积约 1.49 亿平方公里,扣除南极约 1,400 万,剩下约 1.35 亿,对得上。
除南极外还有一处边界:六十度北纬以北。产品页只字未提,技术文档第二节写得很清楚:六十度北纬以上没有 SRTM 高程,用了 HYDRO1k 的粗分辨率高程填补,因此该区域的数据质量明显下降。
这对研究者有具体后果。北纬六十度以上的区域,包括格陵兰、北欧北部、加拿大北部、西伯利亚大部分,它们的流域边界精度与中低纬度不是一个量级。在这片区域上做精细的水文模拟,要先把这一条放在心上。
6.3 平均面积这个数的含义
130.6 平方公里是官方给的平均值。这个数只在最细一级才有意义,而且是个被两条规则拉偏的平均。
一条是 100 平方公里的支流门槛。它把大量单元压在这个数附近。
一条是 250 平方公里的强制细分线。它把本可能巨大的单元切小。
两条合起来的结果,是最细一级的分布集中在 100 到 250 平方公里之间。欧洲 lev12 的中位数是 134.9 平方公里,与官方那个 130.6 很接近。
6.4 平均不等于均匀
平均 130 平方公里,不代表每个都是 130。
最细一级单条记录的最小面积,欧洲是 0。有一条 SUB_AREA 恰好等于 0 的记录。这不是错值,是一个退化的多边形,可能是某个像元级别的碎片。
最大值在欧洲是 699.4 平方公里,明显高于 250 那条强制细分线。这说明强制细分不是百分之百执行的,或者执行之后被后续处理合并了。
分布的两端都伸得很远,这是「平均」两个字最容易误导人的地方。用平均值做容量估计时,要按平方公里的总量做,不要按多边形个数 × 平均值。
6.5 九个洲包的实际体积
| 洲包 | 体积 | 说明 |
|---|---|---|
| 非洲 af | 524 MB | 最大,一级单元只有一条记录 |
| 亚洲 as | 359 MB | |
| 欧洲与中东 eu | 344 MB | |
| 南美 sa | 319 MB | |
| 北美与加勒比 na | 302 MB | |
| 西伯利亚 si | 278 MB | |
| 澳大利亚 au | 186 MB | |
| 北美北极 ar | 138 MB | |
| 格陵兰 gr | 46 MB | 最小 |
九个包加起来约 2.5 GB。这是压缩后的体积,解压之后会膨胀数倍,因为 shapefile 的坐标以双精度存储,且没有压缩。
真正占空间的是 shp 文件。以欧洲为例,十二个层级合起来解压后近 2 GB,其中 lev12 单独一个 shp 就 185 MB。
6.6 只需要一层的时候
如果只想用某一层,官方提供了按层级单独下载的路径:每个洲、每个层级一个文件。
这条路径在体积上是省得最明显的。想用欧洲的十级,只需下载约 20 MB,而不是 344 MB。
代价是三个:要自己确认洲代码、要自己确认层级号、九个洲要下九次。
6.7 带湖版本的额外代价
带湖版本的文件名多一段,体积与标准格式相近,但结构更复杂:属性表多了 Side 与 Lake 两列,HYBAS_ID 末位不再恒为 0,部分子流域被沿河劈成左右两半。
技术文档里对这套版本的告诫写得很重,几乎每一段都在提示「这一点在特殊情形下不成立」。选择它时应当接受一个前提:它的拓扑是在标准格式的基础上加了一层湖泊逻辑,这层逻辑有例外。
§7 阅读本节前:三种评价错位
7.0 先摆正评价框架
用之前先确认一件事:你手里的标准,是不是这份数据承诺过的东西。
它承诺的是:给出一套一致口径的全球子流域边界,配一套能做拓扑查询的编码。它不承诺的是:河道的精确形态、湖泊的精确边界、行政单元的精确对齐、逐年的时间变化。
拿后四样去评价它,评价的其实是另一个产品。
7.1 错位一:拿高分辨率河道数据反推边界精度
用一份一米级的高程或河网,去比对 HydroBASINS 的边界,量出几十到几百米的偏差,然后宣布边界不准。
这个做法忽略了一件事:这份数据的分辨率是十五弧秒,赤道处一格约五百米。边界精度不可能优于底图分辨率。拿厘米级的真值去检验一个五百米网格派生的边界,量出来的差值是网格的,不是算法的。
真正有意义的问题是:在五百米网格这一层,边界的形状对不对?答案是,在山地与丘陵区对得很好,在平原、湿地、冰川与湖泊密集区对得一般,因为流向在这些地方本身就不稳定。
7.2 错位二:拿行政区划要求把流域切开
「这个流域应该按县界切成两半」——这句话成立,但它要求的不是 HydroBASINS 做的事。
它画的是水的边界,必须沿分水岭走。行政区划的边界要沿着历史、人口与地形走,两者在几何上必然交叉,在很多地方必然不全重合。
正确的用法是拿它和国家或省界做空间相交,得到「每个行政单元覆盖的各子流域面积」。这种做法保留了水的完整边界,只是给每块地加了行政标签。反过来做——把流域沿行政边界切开——得到的就不再是流域了。
7.3 错位三:拿湖泊数据要求湖里没有边界
翻开带湖版本,会发现湖面里仍然有流域边界。翻开标准版本,也一样。
技术文档专门解释了:标准格式按流向栅格切分,湖面在实际中虽然是一片水,但在栅格上仍然有流向,所以仍然会被切出子流域。文档的原话是,这些特定子流域的形状可能不反映真实的子流域边界,但它们的拓扑(连通性)穿过整个湖泊仍然成立。
这是设计上的取舍:宁可让湖面上有看起来奇怪的边界,也要保住拓扑的完整性。想遮盖,自己叠一层湖面即可。
7.4 DAIMS 简表
| 维度 | 情况 | 说明 |
|---|---|---|
| 来源可溯 | 强 | HydroSHEDS 底图逐层点名,附完整引用 |
| 方法透明 | 强 | 门槛、强制细分线、三处人工处理全部写明 |
| 版本可辨 | 中 | 只有 v1c,文档封面标 1.c,文件名标 v1c |
| 更新节奏 | 弱 | 2014 年后无整版替换 |
| 不确定度 | 弱 | 无逐条误差,只有对六十度北纬的定性提示 |
| 空间完整度 | 中 | 全球除南极,北极区质量明显下降 |
| 时间信息 | 无 | 单一快照,无时间维 |
| 许可清晰度 | 中 | 自定义许可,条款随主文档,不是标准知识共享协议 |
| 访问稳定性 | 强 | 静态直链,十余年未变 |
| 文档完备度 | 强 | 技术文档十余页,逐字段解释,含全部例外条款 |
7.5 一次可以做的自检
在动手分析之前,值得跑三行校验。
第一行:确认 SUB_AREA 的合计等于官方给的覆盖面积。欧洲十二个层级都是 1,785.89 万平方公里,若你的读数是别的,先查单位是不是把平方公里读成了公顷。
第二行:确认没有哪一行的 UP_AREA 小于 SUB_AREA。有则说明表连错了。
第三行:确认 NEXT_DOWN 的落点全在本表内。若出现表外指针,说明你拼接了不同洲的文件而漏了某一块。
§8 常见误读与避坑清单
| 常见说法 | 实际情况 | 证据 |
|---|---|---|
| 「十二个层级叠起来就是更精细」 | 十二层描述同一块地,叠起来面积会按层数放大 | 欧洲十二个层级的 SUB_AREA 合计都在 1,785.89 万平方公里 |
| 「SUB_AREA 是这个流域的全部面积」 | 那是本多边形面积,全部汇水面积在 UP_AREA | §1.5 的案例:同一行 188.5 与 6,106.4 |
| 「UP_AREA 一定大于等于 SUB_AREA」 | 全表成立,可作为表连错时的自检 | 欧洲 lev12 违反数为零 |
| 「十二级有三十亿个单元」 | 全球最细一级 51.3 万个,十二三级合计 188 万个 | 九个洲逐层 dbf 记录数合计 |
| 「层级越高细分越均匀」 | 十一到十二级全球只多 1,104 个,大部分单元早已停止细分 | 各洲 lev11 与 lev12 记录数对比 |
| 「PFAF_ID 是随机编号」 | 前缀即祖先,偶数支流奇数间流域,0 表示该级跳过 | 欧洲 lev12 前五位去重 674 个,等于 lev05 条数 |
| 「PFAF_ID 里没有 0」 | 末位为 0 的占大多数,表示未继续细分 | 欧洲 lev12 末位为 0 的 137,126 条 |
| 「ENDO 等于 2 就是内流区的终点」 | 有 932 条 ENDO 为 2 却仍有下游,是虚拟连接 | 欧洲 lev12 ENDO=2 共 2,826 条,其中虚拟 932 条 |
| 「沿 NEXT_DOWN 一路走就是真实水路」 | 虚拟连接那一段地表上并不通水 | 技术文档对虚拟连接的说明与 ENDO 判定规则 |
| 「NEXT_DOWN 为 0 就是流入海」 | 还有内流汇点这一类,欧洲 lev12 有 1,894 条 | 按 ENDO 与 NEXT_DOWN 交叉计数 |
| 「HYBAS_ID 末位是校验位」 | 是河网左右侧标记,只有带湖版本才有值 | 标准格式全表末位恒为 0 |
| 「ORDER 为 0 是数据缺失」 | 是合并海岸流域,集合恰好等于 COAST 等于 1 的那一批 | 欧洲 lev12 两者条数完全相等 |
| 「层级零和 lev12 是同一份数据」 | 层级零 16,995 条,lev12 16,990 条,差五花在编码重复 | 格陵兰两图层对照 |
| 「平均面积 130 平方公里,所以每个都这么大」 | 最小值为 0,最大值接近 700,分布两端都伸得很远 | 欧洲 lev12 最小 0、最大 699.4 |
| 「数据覆盖了南极」 | 覆盖 1.35 亿平方公里,明确不含南极 | 产品页原文 |
| 「北纬六十度以上精度一样」 | 那里没有 SRTM 高程,用 HYDRO1k 填补,质量明显下降 | 技术文档第 2 节 |
| 「这是 CC BY 4.0」 | 是自定义 HydroSHEDS 许可,允许商用但条款随主文档 | 产品页许可段落与技术文档 4.1 节 |
| 「带湖版本可以放心做拓扑」 | 湖面可能把不同支流连起来,部分连通被主动切断 | 技术文档 2.3 节的长段告诫 |
| 「有环境属性可以直接建模」 | 十三列全是几何与拓扑量,没有任何环境变量 | lev12 图层 dbf 字段表 |
表里最贵的一条是第一条。它不只是一个统计错误,它会连锁:面积放大之后,按面积加权的所有指标都会偏,然后再被写进模型、写进报告,一路上没有人回头检查那两个图层是不是覆盖了同一块地。
第二贵的是关于 UP_AREA 的那条。§1.5 的案例里,同一行的 188.5 与 6,106.4 差了三十多倍。用它做径流系数,分母选错就意味着结果错一个数量级,而且错得很像真的。
第三贵的是虚拟连接那条。它不会报错,也不会让数字变得离谱,只是让从内流区出发的那条路径多走了一段。核查的办法只有一个:在 ENDO 等于 2 的那批记录上,看一眼 NEXT_DOWN 是不是 0。
还有一类不在表里,因为它不涉及字段,涉及期望:把这份数据当成「全球流域的权威名录」。它不是名录,它是一套基于十五弧秒栅格、按 100 平方公里门槛切出来、再用人工规则处理了岛屿与内流区的图层。名录要的是穷尽,图层要的是可用。
§9 它在本库里的位置
9.1 与 HydroLAKES 的分工,这是最容易混的一对
同一家机构、同一个 HydroSHEDS 体系、同一个下载站,两个产品常被当成一回事。它们不是。
HydroLAKES 画的是水。一个湖一个多边形,岸线是影像与水系图上描出来的,属性里装的是面积、体积、深度、停留时间。它的计数单位是「一个湖」。
HydroBASINS 画的是地。一个子流域一个多边形,边界是流向栅格算出来的,属性里装的是面积、汇水面积、下游指针。它的计数单位是「一块汇水到同一个出口的陆地」。
两者在几何上是互补的。湖在子流域里,一个湖可能只占一个子流域的一小块;一个大的子流域里可能包含几十个湖。
在用途上也不重叠。问「这个湖有多深」,HydroLAKES 答;问「排干这个湖的地有多大」,HydroBASINS 答。
一个实际的接法:把 HydroLAKES 的出水口点落到 HydroBASINS 的某个层级里,得到每个湖所属的子流域。这一步要用空间相交,两套数据的编号互不相通。HydroLAKES 的属性表里没有 HYBAS_ID 这一列。
9.2 与土壤、气象三条线的分工
SoilGrids 给的是地表以下的介质性质,ERA5 给的是大气状态,GHCNd 给的是站点观测,HydroBASINS 给的是把前三者聚合成流域单元的那张网。
四者的接法很标准:先用 HydroBASINS 确定分析单元,再把土壤属性按面积加权平均到子流域,把气象数据按时间序列聚合到子流域,把站点观测按流域归属分配到子流域。
这条链上,HydroBASINS 是唯一一个「没有数值」的环节。它不给任何变量,只给空间单元与单元之间的关系。这正是它的用处:把零散的点与格网,收进一个有拓扑的容器。
9.3 与遥感两条线的关系
Landsat 提供的是像元级的长期观测,可以用来算流域内的植被指数、地表水体、城市扩张。HydroBASINS 提供的是把像元统计汇总成流域指标的那张网。
Overture Maps 提供的是道路、建筑与土地利用的矢量。把它和子流域叠起来,可以算出每个流域的建设用地比例、路网密度,作为人类活动压力的代理变量。
以 §1.5 的案例为例:那块 188.5 平方公里的中游坡地,在十二级里是一个独立单元。把 Landsat 的多年合成影像按这个多边形裁剪,算出植被指数的年际变化,再和它上游那 5,917 平方公里的变化对照,就得到了一组「本地变化 vs 上游来水影响」的分解。这是这份数据最典型的用法:不在于画图,在于提供可以对齐的分析格子。
9.4 检索路径
要找「点观测按流域汇总的边界」,本库里目前只有这一条。要找「全球水体多边形」,去 HydroLAKES;要找「逐小时大气状态」,去 ERA5;要找「站点观测」,去 GHCNd。
流域这个方向在库内是空白,HydroBASINS 是第一块砖。后续可以补的方向有三个:HydroRIVERS(河段线,与这份数据共享同一套汇流逻辑)、HydroATLAS 的 BasinATLAS(同一批子流域,加几十个环境属性)、GRDC(流域出口的站点径流,可用来校验 UP_AREA)。
§10 为什么它能持续,以及 AI 使用声明
10.1 生存逻辑
这份数据活了十来年,靠的是三件事。
第一是编码的稳定性。Pfafstetter 是 1999 年提出的一套成熟方法,HydroBASINS 只是把它应用到了全球尺度。方法不变,编码的含义就不变,十年前写的脚本今天还能跑。
第二是拓扑的完整性。每个多边形都有下游指针,每张图都闭合无环。这让它可以被任何图算法直接消费,不需要先做拓扑修复。
第三是可聚合。前缀相同就是同一父单元,这条性质让跨层级的使用变得廉价。要粗的,按前缀溶解;要细的,取最长的一层。
这三件事合起来,说明它不是一份「精度最高」的数据,而是一份「接口最稳」的数据。
10.2 撑不住的地方
分辨率。十五弧秒是它的天花板,在平原区这一层已经不够了。要做精细的水文模拟,得换 SWORD 或 MERIT-Hydro 这类更新的产品。
北极区。六十度北纬以北用粗高程填补,质量断崖式下降。做高纬度研究,这一段要慎用。
没有环境属性。十三列全是几何与拓扑。要做流域生态或水资源分析,得自己去挂十几个外部数据集。
没有第二版。v1c 之后没有整版替换。SRTM 之后的 SRTM v3、Copernicus DEM 都没被吸收进来。用它做 2026 年的分析,几何仍然是十几年前的。
10.3 用它的三条纪律
第一,先把层级定死,再动手。不要在分析中途换层级,更不要把两个层级的面叠在一起。
第二,UP_AREA 与 SUB_AREA 分清用途。分母用哪个,决定了结果的数量级。
第三,虚拟连接单独处理。ENDO 等于 2 且 NEXT_DOWN 不为 0 的那批记录,要么显式断开,要么显式保留,不要默认。
10.4 AI 使用声明
本文的文本由 AI 辅助撰写,事实核验基于 HydroBASINS 官方产品页、随包分发的技术文档 v1.c(十四页),以及九个洲标准格式压缩包中一百一十七个 shapefile 的 dbf 属性表。
正文中所有字段名、层级记录数、面积合计、极值、类别计数、示例记录的数值,均来自对 dbf 文件的直接解析。方法与规则说明来自技术文档;覆盖面积、平均面积与引用来自官方产品页;压缩包体积来自官方下载链接的响应头。
未下载带湖版本,因此未核验其 Side 与 Lake 字段的实际分布;未对 shp 文件做任何几何运算,所有面积均读自 SUB_AREA 与 UP_AREA 列;未独立验证拓扑图的连通性以外的图论性质。
附录 A 属性速查
| 列名 | 类型 | 含义 | 单位 | 陷阱 |
|---|---|---|---|---|
| HYBAS_ID | 整数 11 | 唯一标识 | 无 | 十位结构:大洲 + 层级 + 序号 + 侧别 |
| NEXT_DOWN | 整数 11 | 下一个下游 | 无 | 0 表示无下游;虚拟连接也指向非零值 |
| NEXT_SINK | 整数 11 | 下一个下游终端 | 无 | 与 MAIN_BAS 口径不同 |
| MAIN_BAS | 整数 11 | 主干流域出口 | 无 | 按它分组可连小内流区一起归 |
| DIST_SINK | 小数 10,1 | 到下游终端距离 | 公里 | 虚拟连接记零距离 |
| DIST_MAIN | 小数 10,1 | 到主干出口距离 | 公里 | 同上 |
| SUB_AREA | 小数 10,1 | 本多边形面积 | 平方公里 | 不是流域面积;存在 0 值 |
| UP_AREA | 小数 10,1 | 累计汇水面积 | 平方公里 | 不含虚拟连接并入的内流区 |
| PFAF_ID | 整数 13 | Pfafstetter 码 | 无 | 位数等于层级;0 表示跳过 |
| ENDO | 整数 6 | 内流区三态 | 无 | 2 且 NEXT_DOWN 非零为虚拟连接 |
| COAST | 整数 6 | 海岸聚合标记 | 无 | 与 ORDER 为 0 的集合完全重合 |
| ORDER | 整数 6 | 河序 | 无 | 0 为海岸聚合单元,不是缺值 |
| SORT | 整数 11 | 原始流水号 | 无 | 原始顺序为下游到上游 |
附录 B 术语表
| 术语 | 含义 |
|---|---|
| Pfafstetter 编码 | 一种按水系拓扑给流域编号的十进制体系,四条最大支流编偶数,其间流域编奇数 |
| 间流域 | 两条支流之间不流入任何一条的那块地,编码为奇数,面积可以任意小 |
| 嵌套 | 上一层的每个多边形恰好等于下一层若干多边形的并集 |
| 子流域细分门槛 | 两条支流各自上游面积都达到 100 平方公里时在此分叉 |
| 强制细分线 | 超过 250 平方公里的子流域沿主干流强行插入断点 |
| 内流区 | 没有地表出海口、水在盆地内蒸发或下渗的汇水区 |
| 虚拟连接 | 给小内流汇点设的一条指向下游多边形的假边,使归属连续但地表不通水 |
| 海岸聚合单元 | 若干条入海小流域合并成的单元,COAST 等于 1,ORDER 为 0 |
| 跳过位 | Pfafstetter 码中因面积容差未继续细分而填 0 的那一位 |
| 层级零 | 标准格式额外提供的图层,含全部最细多边形与 pfaf_1 至 pfaf_12 十二列编码 |
| 侧别 | 带湖版本中把子流域沿河劈开后,用 L、R、M 标注的左右关系 |
| 汇水面积 | 从源头算到某出口的全部地表面积,含该出口所在多边形自身 |
| HydroSHEDS | 基于航天飞机雷达地形数据派生的全球水文基础层,本数据的母体 |
| HYDRO1k | 美国地质调查局的千米级全球高程衍生库,六十度北纬以北用以填补高程空缺 |
| HydroRIVERS | 同体系的河段矢量产品,与这份数据共享汇流逻辑 |
| BasinATLAS | HydroATLAS 的流域分册,完整包含这里的全部子流域并增补环境属性 |
附录 C 常见误读 FAQ
问:能不能只用十二级,其他层级不要?
可以。十二级是最细的一层,覆盖完整。但如果上游要到层级三才做的粗汇总,就得重新下载,或者用十二级的前缀去溶解。
问:面积加起来为什么和国土面积对不上?
先看加的是哪一层,再看是不是把两层叠起来加了。单层的合计在同一个大洲上是恒定的,跨层加总必然偏大。
问:为什么同一个地方在两个层级里的面积不一样?
因为多边形边界在两个层级上各自独立绘制。逻辑上父单元等于子单元合起来,几何上会有几十米的错位。做严格核对用 SUB_AREA 列。
问:NEXT_DOWN 指向的那块地,真的是水流下游吗?
绝大多数是。例外的就是虚拟连接:ENDO 等于 2 且 NEXT_DOWN 不为 0 时,这一条是人为补上去的归属边,地表上并不通水。
问:能不能用它做洪水淹没分析?
不能直接用。它没有高程、没有河道断面、没有流量。它能做的是提供分析单元,把别的数据汇总进来。
问:为什么湖面里还有流域边界?
因为标准格式按流向栅格切分,湖面在栅格上仍具流向。文档明确说这些边界的形状可能不反映真实分水岭,但拓扑穿湖成立。
问:带湖版本是不是更好?
看用途。要干净的拓扑与编码聚合,用标准格式。要对湖泊做研究,用带湖版本,同时接受文档列出的那一长串例外。
问:这份数据还会更新吗?
截至核验时,官方产品页标的是 version 1,技术文档是 1.c,日期 2014 年 7 月。官方页面没有给出新版计划。
问:能不能拿它训练流域分割模型?
可以,但要清楚标签的性质:它是高程派生的规则输出,不是人工标注的真值。模型学到的会是这套规则,包括它的门槛与强制细分线。
编辑说明
核验时间 2026-10-30。方法:打开 HydroSHEDS 官方 HydroBASINS 产品页,逐句核对层级数、门槛、覆盖面积、平均面积、许可与引用;下载技术文档 v1.c 十四页并通读,逐节核对分叉规则、三级人工编码、三处人工处理(岛屿、内流区、海岸聚合)、跳级规则与带湖版本的例外条款;下载九个洲标准格式压缩包,逐一解压一百一十七个 shapefile,解析每个 dbf 的头部得到字段清单与记录数,对全部记录做全量扫描,统计层级记录数、SUB_AREA 合计、UP_AREA 极值、ENDO 与 COAST 与 ORDER 的交叉分布、NEXT_DOWN 的落点闭合性,并对欧洲与格陵兰两个洲做跨层级前缀一致性检验。
与常见转述不一致处已在正文逐条更正,主要有五处:最细一级的全球多边形数逐洲合计为 512,736,与产品页「一百万个」的措辞相差约一倍;十二级相对十一级全球只增加 1,104 个多边形,十二级是名义上限而非均匀细分深度;ENDO 等于 2 且有下游的虚拟连接在欧洲 lev12 有 932 条,直接沿 NEXT_DOWN 遍历会误判连通;HYBAS_ID 末位在标准格式中恒为 0,侧别只在带湖版本出现;层级零与最细一级的条数不相等,差额来自四组重复编码。
未下载带湖版本,未核验 Side 与 Lake 字段的实际取值分布;未对任何 shp 文件做几何运算,所有面积均读自属性列;未独立验证拓扑图的连通分量数与环检测。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- hydrolakes — 共享标签:公共卫生与流行病学 / 全球健康 / 调查数据
- dhs-program — 共享标签:公共卫生与流行病学 / 全球健康 / 调查数据
- ghdx — 共享标签:公共卫生与流行病学 / 全球健康 / 调查数据
- world-health-survey — 共享标签:公共卫生与流行病学 / 全球健康 / 调查数据
- gho-steps — 共享标签:公共卫生与流行病学 / 全球健康 / 调查数据
- share — 共享标签:公共卫生与流行病学 / 全球健康 / 调查数据
- sage-survey — 共享标签:公共卫生与流行病学 / 全球健康 / 调查数据
- lasi — 共享标签:公共卫生与流行病学 / 全球健康 / 调查数据
- global-burden-of-disease — 共享标签:公共卫生与流行病学 / 全球健康
- nhanes — 共享标签:公共卫生与流行病学 / 调查数据
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

