简介:这份2024年北京市河流水系矢量图层数据集,面向需要水域底图的GIS数据分析师、规划研究者与自然资源相关从业者,可作为水系制图、空间分析、工程选址及可视化应用的基础数据。压缩包内共11个文件,以shp矢量主文件为核心,配套shx几何索引、dbf属性信息、cpg字符编码与prj坐标投影说明,便于在ArcGIS、QGIS、FME等主流工具中直接加载,也方便用Python的pyshp、geopandas等进行批处理;整体包体仅2.64MB,但覆盖了线状河流与面状水体两类要素,包含数千至上万条细化记录,轮廓完整、细节较丰富。目前已有160人学习下载。拿到后可直接制作北京水域专题图、开展缓冲区与邻近分析,或借助包内转换脚本将数据输出为GeoJSON,为Web地图、大屏可视化、三维场景等开发环节提供稳定数据入口;线面分层清晰,也适合教学演示和项目原型快速搭建,在河网密度计算、洪水淹没模拟等场景能显著减少数据预处理量。
1. 河流水系矢量图层下载,卡住的多半不是下载这一步
在水利、防汛、规划与河长制相关的项目里,经常需要一套北京范围内的河流水系矢量底图:既要线状河网,也要面状水库湖泊,最好还带干流、支流、渠道的分级。打开网盘搜“2024 北京市河流水系矢量图层 shp”,下载链接很多,真正能用起来的没几个。常见情况是解压后发现坐标系缺失、属性表空白,或者河流被切成一截截短线;放进 ArcGIS Pro 之后,和行政边界、道路数据一叠加,错位从几十米到几公里不等。所以这套流程真正要解决的问题是:先把数据源筛对,再统一坐标基准,最后补齐属性和拓扑,让它能直接参与叠加分析和出图。下面按这条链路逐段展开,中间涉及的命令与参数都给了可执行的版本。
2. 数据源筛选与下载实操:把河流水系矢量图层拿到本地
2.1 先想清楚去哪下载:四个来源各有边界
常见做法是先从公开数据平台拿一套权威底图,再用众源数据补充小水系。对北京而言,稳定的水系数据来源有四个,侧重点完全不同。第一个是 OpenStreetMap(通过 QGIS 的 QuickOSM 或 OSMnx 拿),它的水系表达细,街道级河道、暗渠都有,但属性不规整,很多线段没有河名;第二个是全国地理信息资源目录服务系统提供的公开基础地理数据,里面有完整的水系层级,属性带分类代码,适合正式项目建档;第三个是地理空间数据云下载 DEM,自己用流向算法提取河网,适合做水文分析和汇流计算,但提取结果不是现成的“河”;第四个是北京市各区水务部门的专题发布数据,这类数据最贴合本地业务,但往往只覆盖本区,拿到后还要做跨区拼接。
这四个来源怎么选,取决于你最终拿它做什么。给 Web 端做可视化展示,OSM 足够,胜在要素全、更新快;要跟全国路网、行政区划做套合分析,必须用 CGCS2000 框架下的权威要素;要做淹没模拟,那就得 DEM 提取。日常项目里我一般先下全国基础地理底图,再用 OSM 补小河道,两条路能互相校验。
| 来源 | 数据特征 | 原始坐标系 | 适用场景 |
|---|---|---|---|
| OpenStreetMap | 河名不全,线面分离 | WGS84 经纬度 | Web 可视化、快速底图 |
| 全国地理信息资源目录服务系统 | 要素完整、带分类码 | CGCS2000 | 正式制图、空间分析 |
| DEM 提取河网 | 栅格流线,无属性 | 与 DEM 一致 | 水文分析、汇流关系 |
| 水务专题发布 | 分级明确,含水利工程 | CGCS2000 / 高斯投影 | 河长制台账、一河一策 |
2.2 用 QuickOSM 拉取北京市 waterway 数据的最小操作
如果只在 QGIS 里快速看一套北京水系,QuickOSM 是效率最高的方式,不需要写代码。安装完插件后,顶部菜单栏在 Web → QuickOSM → QuickOSM。面板里 Key 填 waterway,Value 留空,Place 一栏填“北京市”,要素类型勾选“线”,点击运行查询。
这里有个常见误区:很多人以为 Place 传“北京市”就能严格按行政区边界裁剪,实际 QuickOSM 是把地名解析成 Overpass 的 area 对象,area 的边界和民政边界不完全一致,偶尔会带出河北一两个村庄的河道。判断是否拉多了,看要素数量:北京全域的 waterway 线要素一般在几千到上万条,如果只有几百条,说明查询区域没解析到市级,只落在某一个小范围。
面板背后生成的 Overpass 查询如下:
[out:json][timeout:60]; area["name"="北京市"]->.a; way["waterway"](area.a); out;[timeout:60]是查询超时上限,单位秒;->.a把查询到的区域集合保存为临时变量;(area.a)限定在区域内检索。如果结果数据量太大报超时,可以改成[timeout:180],或者把北京拆成各区分别拉取,避免 Overpass 主服务端压力过大。
2.3 用 OSMnx 把北京水系批量落成 shp
QuickOSM 适合交互式查看,但要做自动化流程,我一般直接用 Python 的 OSMnx 库。它内部替你处理了 Overpass 请求、坐标解析、GeoDataFrame 构建,一段脚本就能把北京全域水系落成本地 shp 文件:
import osmnx as ox gdf = ox.features_from_place("北京市", tags={"waterway": True}) gdf = gdf[gdf.geometry.geom_type.isin(["LineString", "MultiLineString"])] gdf["kind"] = gdf["waterway"].fillna("").astype(str) gdf = gdf[["kind", "name", "geometry"]] gdf.to_file("beijing_rivers_raw.shp", encoding="utf-8")这段脚本的核心是features_from_place,它先把“北京市”解析成行政区范围,再拉取所有带 waterway 标签的要素;第二行过滤掉面状水体,因为我们要的是河网线图层;kind列保留 river、stream、canal 等类型,后续分级筛选靠它;最后to_file写出 shp 文件族。运行前先pip install osmnx,装的时候会把 geopandas、shapely 一并带上。
2.4 拿到压缩包后先检查 shp 的文件族完整性
很多人从网盘下载“北京市河流水系 shp 数据.zip”,解压后只有一个 .shp 加几个小文件,直接拖进软件发现打不开。shp 不是单文件格式,而是一组文件族,缺了关键后缀,软件只能显示几何、读不出属性。检查命令行放在下面。
unzip beijing_rivers.zip -d ./beijing_rivers ls -la ./beijing_rivers/ cat ./beijing_rivers/*.prjls -la看文件族是否齐全,.shp管几何、.shx管索引、.dbf管属性、.prj写坐标系文本;最后一条cat .prj直接读出坐标系定义,这决定了后面是该做“投影转换”还是“定义投影”。
| 文件后缀 | 职责 | 缺失后果 |
|---|---|---|
| .shp | 几何坐标 | 直接打不开 |
| .shx | 几何索引 | 读取极慢甚至报错 |
| .dbf | 属性内容 | 图能看到但无属性表 |
| .prj | 坐标系定义 | 位置偏移、无法对齐 |
| .cpg | 字符编码声明 | 中文属性乱码 |
.cpg缺失是中文乱码的主要来源。旧数据常用 GBK 编码,而 ArcGIS Pro 默认按 UTF-8 读,解决办法是补一个.cpg文件或导入后用字段映射重算,后面第四章会展开。
3. 坐标系、属性表与拓扑修复:让水系 shp 对齐北京地面
3.1 先看 .prj:WGS84 还是 CGCS2000 决定后续操作
北京地区水系数据下载后,坐标系基本是两种情况:OSM 出来的是 WGS84 经纬度,全国基础地理数据多带 CGCS2000 经纬度。经纬度坐标本身没问题,但直接做长度统计、缓冲区分析,单位是度而不是米,结果没法用。项目上统一的做法是把数据投影到高斯克吕格投影下。
北京经度范围大致在 115.7°E 到 117.4°E,3 度带通常落在中央经线 117°E 的带内,西部部分区域用 114°E 带。实际操作时直接在投影工具里搜索“CGCS2000 3 Degree GK Zone 39”,不要自己去记 EPSG 编号,搜索框能按名称过滤。
| 目标投影名称 | 中央经线 | 适用区域 |
|---|---|---|
| CGCS2000 3 Degree GK Zone 38 | 114°E | 北京西部区县 |
| CGCS2000 3 Degree GK Zone 39 | 117°E | 北京大部分地区 |
| CGCS2000 3 Degree GK CM 117E | 117°E | 中心线对齐,通用 |
注意区分“投影”和“定义投影”:如果图层本身没有 .prj 文件,需要先用“定义投影”告诉软件数据基于哪个坐标系,再做“投影”到目标坐标系。顺序反了,转换出来的位置就是错的,这类错位在数据叠加时根本查不出原因。
3.2 在 ArcGIS Pro / QGIS 里做投影转换并重算长度
ArcGIS Pro 里把 shp 拖进地图,右侧图层属性里查看源坐标系。如果显示“未知”,右键图层选择 Properties → Source,先定义源坐标系。然后打开工具箱搜索“Project”,输入要素选北京河流图层,输出坐标系选 CGCS2000 3 Degree GK Zone 39,执行后生成新 shp。
QGIS 里的等价操作更直接:右键图层 → Export → Save Features As,Format 选 ESRI Shapefile,CRS 一栏选目标投影,文件名另存。QGIS 会生成带 .prj 的新文件,原数据不会被动过。
投影完成后的第一件事是重算长度字段。经纬度坐标下算出的长度单位是度,几乎没法用于报告。用 ArcPy 在 Pro 里算:
arcpy.management.AddField("beijing_rivers_raw.shp", "LEN_M", "DOUBLE") arcpy.management.CalculateField("beijing_rivers_raw.shp", "LEN_M", "!shape.length@meters!", "PYTHON3")AddField新建一个双精度字段存长度,!shape.length@meters!返回当前坐标系下的真实地面长度,单位米;PYTHON3是 ArcGIS Pro 的字段计算器解析器,旧版 ArcMap 要写成PYTHON。这里有个隐蔽的坑:如果图层在工程里被动态投影成 Web 墨卡托(EPSG:3857),shape.length@meters返回的是墨卡托距离,不是高斯平面距离,结果会偏大,所以算长度前必须确认图层自身的坐标系已经切到高斯投影。
3.3 河流短线与悬空端点怎么补齐
公开数据里最让人头疼的河流拓扑问题是“断头”。河道在制图时按图幅切割,每条河在图幅边界被硬生生断开,支流汇入干流的位置没有公共节点,做连通性分析时河网就像一堆散线。
QGIS 里先开 Topology Checker 插件(Vector → Topology Checker),规则选“不得有悬空端点”,放大看报错位置。小范围手工修节点能接受,全市范围必须用自动清理。GRASS 的 v.clean 是常用工具:
v.clean input=beijing_rivers output=beijing_rivers_clean \ tool=snap,break,rmdangle thresh=20tool=snap,break,rmdangle按顺序执行:snap 把相距 20 米内的节点吸附到一起,break 在交叉点打断线段,rmdangle 删除无法接上主网的悬空短线。需要提醒的是,v.clean 会把一条完整河流打断成大量小段,所以清理完要根据河名或 kind 字段做一次融合(Dissolve),按相同河道名称合并,恢复连续性。
3.4 用 GeoPandas 批量检查与清理
交给 Web 系统或者做批量质检时,我最常用 GeoPandas 先摸一遍底,把空几何、非法几何、多部件要素清掉,避免下游加载报错。
import geopandas as gpd from shapely.validation import make_valid gdf = gpd.read_file("beijing_rivers_raw.shp") gdf = gdf[gdf.geometry.notna() & ~gdf.geometry.is_empty] gdf = gdf[gdf.geometry.geom_type.isin(["LineString", "MultiLineString"])] gdf["geometry"] = gdf.geometry.apply(make_valid) gdf = gdf.explode(ignore_index=True) gdf.to_file("beijing_rivers_clean.shp", encoding="utf-8")make_valid是 Shapely 2.x 推荐的几何修复入口,能把自相交线、退化环这类非法几何转成合法表达;explode将 MultiLineString 拆成单线,前端渲染和按段统计都方便。整段代码跑完,输出一个几何干净、单部件、坐标系继承原文件的 shp。注意输出后最好显式加上crs="EPSG:4326"或对应高斯投影,因为有些源文件缺 .prj,GeoPandas 读进来时空坐标参考,写出去也还是空。
4. 在 ArcGIS Pro 里把北京河流 shp 用起来
4.1 加载 shp 并处理乱码与影像叠加
把清理好的 shp 拖进 ArcGIS Pro 时,建议用 Catalog 面板连接文件夹后右键添加,而不是直接拖文件到视图。视图里图层显示后,打开属性表看中文河名。如果显示成问号,通常是 .cpg 缺失导致的编码误判。一个实用的处理技巧是先在 QGIS 里用不同编码重新加载一次,右击图层选择 Set Layer Encoding,分别试 UTF-8 和 GBK,找到中文正常的那次另存为新 shp,再拿回 Pro 里用。
同一工程里还要叠加遥感影像时,用 Add Data 选择栅格文件。如果影像位置和河流对不上,启动 Georeference 工具,在影像上取河道拐角和已知位置的桥梁路口做控制点,一般取 4 到 6 个点够完成配准。别去调图层的透明度来凑重合,配准误差不会因此消失。
Georeference 操作要点:控制点均匀分布,优先选河道转弯、桥梁、水库坝体等特征点4.2 按属性筛选河网等级
北京河流水系数据里常见的 waterway 值有 river、stream、canal、drain,分别对应河流、溪流、干渠、排水沟。业务上要出“主要河网图”时,直接在图层属性里做定义查询,SQL 写法如下:
waterway IN ('river', 'stream', 'canal') AND name IS NOT NULLIN列表筛掉排水沟等人工设施,name IS NOT NULL去掉无名的零碎线段。定义查询的好处是只改变视图显示,不生成新文件,后续叠加、制图、导出都基于同一个筛选结果,避免多次导出临时图层造成版本混乱。如果要把筛选结果单独存一份,右键 → Data → Export Features,输出为新的 shp 或要素类。
4.3 叠加行政区边界做空间连接
河流跨区分布,统计每个区的河道长度,是河长制项目的常规需求。ArcGIS Pro 里的工具叫 Spatial Join(空间连接)。参数设置上,目标要素选北京各区行政边界,连接要素选河流线图层,连接操作选 JOIN_ONE_TO_MANY,匹配选项选 INTERSECT。
这样连接后,每条河流线段会被复制到它穿过的每个区名下,再按区聚合统计长度:
SELECT 区名, SUM(LEN_M) AS 河流总长 FROM Joined_Rivers GROUP BY 区名这里的关键是 JOIN_ONE_TO_MANY 而不是 JOIN_ONE_TO_ONE。一条河流穿过三个区,如果用 ONE_TO_ONE,连接结果只保留第一次命中的区,另外两个区就统计漏了。匹配选项也别用 WITHIN,跨区河流不会完全落在单个区内部,用 INTERSECT 才能按“穿过即统计”的口径取数。
4.4 导出成果并转 GeoJSON / 3D Tiles
成果导出分三种常见格式。给正式项目存档用 File Geodatabase 要素类,右键图层 → Data → Export Features,输出类型选 File Geodatabase;给 Web 前端预览用 GeoJSON,Pro 自带该格式,右键导出即可;做三维场景展示则需要转 3D Tiles。较新的 ArcGIS Pro 提供实验性的三维瓦片创建工具,老环境用 CesiumLab 这类转换器,前提是先把线要素赋上 Z 值,否则转出来的河道是平的,看不出地形关系。
shp 转要素类时有个隐藏问题:shp 的 dbf 字段名限制 10 个字符,中文名往往变成截断字符串,导出到要素类后字段别名丢失。所以在导出前要用属性表里右键字段 → Aliases 把中文名重新维护一遍,否则图例和报表里全是LEN_M、NAME_1这类字段代码。
5. 把 shp 转成 txt:脱离 GIS 场景的边界落地
5.1 一条 ogr2ogr 命令输出 WKT 文本
不是所有下游系统都能读 shp。给前端地图组件喂数据、给后端做空间判定,甚至给 AI 模型做训练样本标注,最常见的交付格式是带 WKT 的纯文本。用 GDAL 自带的 ogr2ogr,一条命令就能从清理后的 shp 生成可读文本:
ogr2ogr -f CSV beijing_rivers.csv beijing_rivers_clean.shp \ -lco GEOMETRY=AS_WKT -lco CREATE_CSVT=YES-f CSV指定输出格式;-lco GEOMETRY=AS_WKT把几何写成 WKT 字符串;-lco CREATE_CSVT=YES额外生成一个 .csvt 文件,声明每列的类型,避免在 Excel 或 Tableau 里打开后经纬度列被误判成文本,丢失小数精度。
5.2 导出 WKT 后用边界框验证坐标系
转出来的文本里如果带的是高斯投影坐标,拿给前端 Leaflet 用会完全偏离底图。写文件前先投影回 WGS84,再导出,同时打印边界框做一次自检:
import geopandas as gpd gdf = gpd.read_file("beijing_rivers_clean.shp").to_crs(epsg=4326) gdf["wkt"] = gdf.geometry.to_wkt() gdf[["name", "wkt"]].to_csv("beijing_rivers_wkt.txt", index=False, sep="|", encoding="utf-8") minx, miny, maxx, maxy = gdf.total_bounds print(minx, miny, maxx, maxy)to_wkt()把每个要素几何转成标准 WKT;total_bounds返回整个图层的边界框。北京 WGS84 下的合理范围大约是经度 115.4 到 117.6、纬度 39.4 到 41.2,如果打印结果出现 4 开头的八位数值,说明源文件还是高斯投影,to_crs(epsg=4326)没有真正生效,需要先给源数据补定义坐标系再投影。
5.3 面状水体只保留外边界线的快捷做法
txt 交付场景里还有个高频需求:面状水体(比如水库、湖泊)只要外边界线,不要整个面。GeoPandas 里每个 Polygon 的.exterior属性直接给你外环线:
gdf_poly = gdf[gdf.geometry.geom_type == "Polygon"] gdf_line = gdf_poly.copy() gdf_line["geometry"] = gdf_poly.geometry.exterior gdf_line[["name", "geometry"]].to_file("beijing_lakes_shoreline.shp", encoding="utf-8").exterior只取外环,有孔洞的水面会丢弃内环,正好满足“只要岸线”的需求。执行后打开新 shp,一个一个检查面和线数量是否一致。多部件面要素(MultiPolygon)在这个操作里会被跳过,先对几何做explode(ignore_index=True)再取 exterior,否则部分湖体丢得无声无息。用 QGIS 打开原始面图层与生成的岸线图叠加对比,顶点数一致、岸线贴合水面边界,这组数据就算真正可交付了。
本文还有配套的精品资源,点击获取