ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ArcGIS下长江中游水系shp处理:坐标系、拓扑与裁剪全攻略

2026/9/11 23:03:07 拓冰建站 浏览量
ArcGIS下长江中游水系shp处理:坐标系、拓扑与裁剪全攻略 简介面向ArcGIS使用者及地理信息相关专业研究者的长江流域中游干流区间基础地理数据包以shp矢量水系与dem90m栅格地形为核心涵盖制作专题图所需的核心底图资源可支撑流域可视化、地图制图及初步空间分析。包内共71个文件既包括shp、dbf、prj、sbn等ArcGIS矢量图层常规配套文件也含有adf、nit、dat等栅格数据格式以及mxd工程模板和jpg、pdf、eps三种已出图成果整体压缩包约28.47MB目录已分层整理便于按需取用。目前已有1663人学习下载适合需要快速获取长江中游流域底图、以ArcGIS开展实习或项目制图的人员。mxd工程内已建立图层链接思路具有一定GIS基础的使用者可按常规流程关联解压后的矢量与栅格文件即可输出设定区域的地形水系复合图若完全不需要自行调整也可直接使用附带的图片成果省去制图操作。1. 把长江干流中游区间的水系 shp 拖进 ArcGIS 之前先分清这三层数据“长江流域干流中游区间”不是行政区边界而是长江干流宜昌至湖口之间、以干流为轴的两侧汇水范围。这类资料解压后通常不是一个 shp而是水系线、子流域面、水文站点和地形图栅格/等高线的组合。很多人拿到手就拖进 ArcMap 或 ArcGIS Pro结果看到河流断线、流域面跨出区间范围、shp 缺 .prj 文件、面积是负值——前 10 分钟不处理坐标系和拓扑后面的裁剪、叠加、出图全都要返工。这篇按我处理中游水系数据时的顺序来写先把 shp 的坐标系和拓扑问题清掉再做区间裁剪和地形图套合最后落到属性导出和脚本化每一步都给到可以直接抄的参数和代码。2. 坐标系统一长江流域干流中游区间的 shp 投影选择2.1 先检查 .prj别让水系 shp 在经纬度下硬算长度面积打开 ArcGIS 后第一件事不是看图层好不好看而是右键图层打开属性切到 Source 选项卡看那个 shp 的 Spatial Reference 到底是什么。我经手的中游水系数据相当一部分直接丢过来一个没有 .prj 的文件ArcGIS 默认按未知坐标系加载叠加 DEM 或影像时要么提示“Unreferenced data”要么要素全部挤到西非沿海。没有 .prj 时先用 Define Projection 指定正确的坐标系原来自带 .prj 但后续工具要求投影坐标时用 Project 转坐标。长江流域干流中游区间的经度范围大约在 106°E 到 118°E 之间按 3 度分带38 带中央经线 114°E、39 带中央经线 117°E 都会跨到。做全区间统一分析时我更倾向于用 CGCS2000 / 3-degree Gauss-Kruger CM 114EEPSG 4549这样一个投影覆盖整个中游不用在分带边界裁来裁去。import arcpy arcpy.env.workspace rD:\yangtze_mid\data for shp in arcpy.ListFeatureClasses(*.shp): out_shp shp.replace(.shp, _prj.shp) arcpy.Project_management( in_datasetshp, out_datasetout_shp, out_coor_systemarcpy.SpatialReference(4549) )这段代码会把工作空间下所有 shp 投影到 CGCS2000 3 度带 114E。注意arcpy.SpatialReference(4549)这里用的是 EPSG 代码ArcMap 10.4 以上和 ArcGIS Pro 都认识如果你手头数据还是西安 80 或北京 54 的老成果不要直接 Project 到 CGCS2000需要先找控制点做七参数转换否则河流整体偏出去几十米。2.2 流域面面积是负值先 Repair Geometry别急着重算热搜里“arcgis 里面积是负的怎么处理”对应的就是 shp 面要素的 ring 方向问题。shapefile 的规则是外环逆时针、内环顺时针一旦数据生产时把环的方向写反ArcGIS 计算出的 Shape_Area 就可能是负数或者面在显示时出现“空洞”和“交叉”两种诡异效果。处理方法很直接ArcToolbox Data Management Tools Features Repair Geometry把输入 shp 选进去Geometry Type 选 ALL按下确定即可。这个工具会重排环方向、删除零长度线段、修复自相交。我一般还会配合 Check Geometry 先跑一遍把问题要素挑出来Repair 完再 Check 一次确认返回的 Errors 为 0。工具位置解决什么问题关键参数Define ProjectionData Management Tools Projections and Transformations给无坐标信息 shp 赋予坐标系只写坐标系不改坐标值Project同目录重投影到目标坐标系Geographic Transformation 可留空或指定Check GeometryData Management Tools Features检查几何错误类型OID 和错误类型输出表Repair Geometry同上修复坏几何Geometry Type 常用 ALLAdd Geometry AttributesData Management Tools Features补算面积/长度等属性支持 GEODESIC 测量这里有个容易被忽略的点Repair Geometry 会改变要素结构修复前最好备份原始 shp。特别是后续要对接水文模型时上游单位可能只认原始要素编码一旦几何重建导致某个子流域面被拆成两个多部件编码就断了。2.3 水系拓扑检查悬挂点、伪节点、自相交分开看水系线 shp 的拓扑问题比面文件更多而且表现隐蔽。常见三类一是悬挂点即河流线的一端没有连到任何其他线二是伪节点两条线在同一个点相交但实际上是同一条河只是被数据生产切成两段三是自相交一条折线绕回来跟自身交叉常见于湖泊出口和弯曲河段。ArcGIS 的拓扑检查必须把数据放进地理数据库。操作顺序在 Catalog 里新建一个 File Geodatabase把 shp 导入要素数据集然后右键数据集新建拓扑。规则按中游水系的情况选下面几种逐一说明拓扑规则冲突含义中游数据适用场景Must Not Have Dangles线端点必须被其他要素覆盖查找断头支流但区间出口处悬挂点要保留Must Not Have Pseudonodes线不能有伪节点同一河流被人为拆分需合并Must Not Self-Overlap线不能自重叠重复采集或多次拼接产生Must Not Self-Intersect线不能自相交河网扭曲时常见Must Be Single Part要素不能为多部件用于面状湖泊被错误聚合拓扑验证完成后错误会列在 Error Inspector 里。修悬挂点时注意边界条件长江干流流出中游区间的那个点以及区间内支流汇入干流的点本来就会出现单线端点这两个位置的悬挂点不能删。真正要删的是中间悬空的短线头多半是数据拼接时的残余线段。伪节点则用“Merge”把相邻两条线合并成一条保留属性以较长线为准。3. 用中游区间边界裁剪水系与流域 shpClip 和 Dissolve 的参数细节3.1 Clip 裁剪水系线XY Tolerance 别随手填ArcToolbox Analysis Tools Extract Clip 是最常用的裁剪工具。输入要素选中游区间的水系线或者流域面裁剪要素选中游区间边界面输出要素类可以直接写成 gdb 里的要素类也可以写 .shp。输出写 .shp 时字段名会被截断为 10 个字符中文字段名还会有变成问号的风险所以能写进 GDB 就写进 GDB。Clip 工具的 XY Tolerance 参数默认是空工具会自动按输出坐标系的最小分辨率处理。中游水体资料常见的问题是这个容差过大比如默认 0.001 度在 114E 这个纬度下约等于 100 米结果干流两岸的小支流被整体吸附到裁剪边界上河流出口位置肉眼可见地偏了。我一般手动填 0.001 米或者干脆填 0。arcpy.Clip_analysis( in_featuresrD:\yangtze_mid\data\river_prj.shp, clip_featuresrD:\yangtze_mid\data\middle_basin_prj.shp, out_feature_classrD:\yangtze_mid\data\river_clip.shp, cluster_tolerance0.001 Meters )这里cluster_tolerance用的是字符串加单位ArcGIS 也接受纯数字。裁剪结果的属性表完整保留原字段但 Shape_Length 不会自动重新计算需要后面用 Add Geometry Attributes 补。Clip 对线要素会沿裁剪边界切开落在边界外的部分不输出落在边界内的线段保留原几何这跟 Intersect 不一样——Intersect 会把线与面相交处的节点重新生成更适合后续做水文拓扑但速度慢得多。3.2 Dissolve 合并子流域再 Erase 扣除上游下游“长江流域干流中游区间”的数据往往被打包成整个长江流域的子流域面。比如数据源是按全国水系一级分区组织的中游区间淹没在“长江流域”这个大面里。这时候先找到子流域面属性表里的分区字段按它 Dissolve 合并出中游区间主体再逐级扣除。arcpy.Dissolve_management( in_featuressubbasin_prj.shp, out_feature_classmiddle_reach_raw.shp, dissolve_fieldBASIN_CODE, statistics_fields[[AREA_KM2, SUM]], multi_partMULTI_PART )dissolve_field选的是分区编码字段statistics_fields里的 SUM 会把所有同编码子流域面积加起来方便跟官方控制断面面积对比。如果拿到的边界已经包含了整段中游区间只缺局部支流就用 Erase 工具把不需要的上游范围扣除掉。Erase 的输入是待处理面和擦除面输出是去掉擦除部分后的剩余几何。操作上要注意Erase 只做几何差不感知流域拓扑扣除完可能出现零碎小面要用 Eliminate 把小于 1 平方公里的碎面合并到相邻大面里。3.3 裁剪成果的 3 项质量检查裁剪不是跑完就结束。我每次裁完中游水系固定做三件事。第一加载裁剪结果和原始 shp目视检查干流出口、主要支流汇入点有没有被边界“吃”掉一小段。第二用 Select By Location 从原始数据和裁剪结果中各统计一次要素数量如果裁剪后数量骤减多半是 Clip Features 本身有问题。第三属性表中对流域面用 Shape_Area 重新排序把面积最大的前 10 个面列出来跟《长江流域防洪规划》里列出的主要子流域面积对一遍误差超过 3% 就要回去查投影和容差。这里有一个常见误用有人为了“让裁出来的河网更平滑”把 Clip 前的 XY Tolerance 设成 0.01 或更大。结果河网节点被大规模抽稀原本弯曲的荆江段岸线变成直线段流域面积损失几个百分点。裁剪时的容差只负责捕捉节点不负责平滑平滑要放到后续的 Simplify Line 里单独做。4. 水系 shp 与地形图套合DEM、等高线和影像校正4.1 从 DEM 提取中游区间等高线叠加前先把范围裁齐“地形图”和“水系流域图”放在一个标题里通常意味着最后要出一张带等高线的水文图。中游区间平原地带多直接用全流域 DEM 提取等高线山区的线会占满整个图幅江汉平原上反而什么都看不到。我先用 Extract by Mask 把 DEM 裁到中游区间边界再按等高距生成等高线这样水系和地形才在同一个范围内说话。from arcpy.sa import ExtractByMask, Contour dem_clip ExtractByMask(dem_mid.tif, middle_basin_prj.shp) contour Contour( in_rasterdem_clip, out_polyline_featurescontour_50m.shp, contour_interval50, base_contour0, z_factor1 ) contour.save(contour_50m.shp)contour_interval在中游山区用 20 米或 50 米平原区用 10 米或 5 米base_contour设 0 表示从 0 米起算实际使用时可以设成 20让等高线数值落在整百上z_factor是垂直比例因子中游 DEM 如果是米制单位填 1 即可。如果 DEM 是高程异常基准比如以海图深度基准面起算要先转成 1985 国家高程基准不然等高线跟水位站数据对不上。4.2 用天地图影像检查岸线偏移再决定要不要 Spatial Adjustment把水系 shp 和地形图套合后另一个高频问题是岸线偏移。中游河湖岸线受冲淤变化影响几年就变一次你拿到的 shp 可能是十年前解译的成果而底图影像是最新的两者看起来就错开几十米。在 ArcGIS Pro 里加载地图影像的标准操作是地图选项卡 Add Data Data From Path输入天地图服务地址ArcMap 则在 Catalog GIS Servers Add WMS Server 里配置。加载后目视检查干流岸线是否骑在影像岸线上。如果偏差普遍在一个方向先不要急着用 Spatial Adjustment 拉去查一下 shp 的坐标系是不是被 Define Projection 强行标成了 CGCS2000而真实数据还是 WGS84两者差几十米很正常。把 .prj 信息改对偏移就会消失。确认坐标系没问题之后偏差依然超过 5 个像素再考虑配准选 812 个均匀分布的桥梁、闸口、固定弯道控制点RMS 控制在 0.5 以下用橡皮页变换校正。橡皮页变换会改线要素的几何形状操作前必须在原始数据上复制一份。另外只为出图而校正的话建议在 ArcGIS Pro 里对图层设置“几何偏移”或者使用地理配准会话不要直接覆盖源 shp否则下次数据处理还要再回归一遍。4.3 水系分级符号化一组可以直接抄的参数中游水系图里最常见的渲染错误是所有河流一个宽度、一个颜色干流和断头渠分不出来。我的设置是长江干流单独用一个图层线宽 1.6 磅颜色 RGB(31, 78, 121)一级支流清江、汉江、洞庭湖水系主河道0.8 磅RGB(56, 110, 170)二级以下支流 0.3 磅RGB(102, 152, 189)。流域面用分级色彩按高程区间分 5 级透明度 20%这样底面等高线还能透出来。河流注记只标注“长江”“清江”“汉江”这些一级名称次要支流标注留到大比例尺出图再加否则图面全被文字占满。5. 中游水系 shp 属性表加工流域编码、长度修正与 shp 转 txt5.1 用字段计算器批量补流域编码拿到的中游水系 shp 属性表里常见状况是有一个中文名称字段但没有流域编码字段。后续入库或者对接模型时没有编码就没法 join 水文站数据。最快的方法是字段计算器里用 Python 解析名称字段批量写编码。def zone_code(name): if name.startswith(清江): return CJZJ-QJ if name.startswith(汉江): return CJZJ-HJ if name.startswith(洞庭): return CJZJ-DT return CJZJ-OTHER代码里的CJZJ前缀表示长江中游区间后面接拼音缩写。字段计算器选 Python 解析器后把这段函数粘贴到预逻辑脚本代码框然后在下面一行输入zone_code(!NAME!)确定后完成赋值。需要注意shapefile 的字段名不区分大小写但会被截断如果你在 ArcMap 里用!NAME!拿字段字段名必须是属性表里实际存在的名字。5.2 用 Add Geometry Attributes 修正裁剪后长度面积前面裁完的河流线Shape_Length 还是原始值。ArcGIS Pro 2.2 以后的 Add Geometry Attributes 工具支持 GEODESIC 测量比老式 Calculate Geometry 更适合跨投影带的中游数据。arcpy.management.AddGeometryAttributes( in_featuresriver_clip.shp, geometry_propertyLENGTH_GEODESIC, length_unitMETERS )LENGTH_GEODESIC会在输出属性表里生成一条LENGTH_GEO字段用来替代被投影变形扭曲的 Shape_Length。面要素同理可以用AREA_GEODESIC生成以大圆面积计算的字段。如果工具版本不支持 GEODESIC至少先用 Project 转到 4549 再计算并且不要在经纬度图层上直接算。5.3 shp 转 txt导出给外业或模型用的标准写法“shp 转 txt”在热搜里很常见但 ArcGIS 自带的 Table to Text 工具导出的是带表头信息的长格式文本模型程序读起来并不方便。更常见做法是用 ArcPy 的 SearchCursor 把需要的字段写成一行一行的 txt。重点是中文用 utf-8-sig 编码否则在记事本和 Excel 里打开都是一堆乱码。with open(rriver_attr.txt, w, encodingutf-8-sig) as f: cursor arcpy.da.SearchCursor( river_clip.shp, [Code, Name, LENGTH_GEO, SHAPEXY] ) for code, name, length, xy in cursor: f.write(f{code},{name},{length:.2f},{xy[0]:.3f},{xy[1]:.3f}\n)SHAPEXY返回的是点要素的代表点坐标对线要素则取线的起点所以导出时如果要知道河流入口位置用SHAPESTARTX和SHAPESTARTY更准确。复杂面要素不要直接依赖SHAPEXY它只给一个点要把洞、多环结构写全需要遍历SHAPE的getPart()方法否则湖泊中间的岛会被丢掉。5.4 批处理导出时容易踩的空值坑光标遍历时字段值为 None 是正常的不能用空字符串拼接。导出前先统计属性表里哪些要素的关键字段是 Null能补则补补不了就统一写成NODATA。另一个坑是坐标小数位导出时如果直接str(xy[0])默认可能输出 17 位小数txt 文件体积爆炸用:.3f固定到三位数对大多数水文分析精度足够需要保留更高精度时再改成:.6f。6. 把整套处理流程固化成一个 ArcGIS 脚本工具再交付6.1 用参数承接中游区间面而不是改脚本常量前面每一节都可以独立跑但在项目交付时我习惯把“投影 → 拓扑修复 → 裁剪 → 计算长度 → 导出 txt”合成一个脚本并用 ArcGIS Pro 的 Add Script 功能包成工具。这样换一个区间边界、换一套水系 shp只需要改参数不用打开代码编辑器。import arcpy arcpy.env.overwriteOutput True arcpy.env.outputCoordinateSystem arcpy.SpatialReference(4549) in_shp arcpy.GetParameterAsText(0) # 输入水系 shp mask_shp arcpy.GetParameterAsText(1) # 中游区间边界 out_txt arcpy.GetParameterAsText(2) # 导出 txt 路径 arcpy.Project_management(in_shp, river_prj, arcpy.SpatialReference(4549)) arcpy.Clip_analysis(river_prj, mask_shp, river_clip) arcpy.management.AddGeometryAttributes(river_clip, LENGTH_GEODESIC, METERS) with open(out_txt, w, encodingutf-8-sig) as f: cur arcpy.da.SearchCursor(river_clip, [Code, Name, LENGTH_GEO]) for code, name, length in cur: f.write(f{code},{name},{length:.2f}\n)arcpy.env.overwriteOutput True让重复运行不会报文件已存在outputCoordinateSystem设置成 4549 后Clip 中间产物的坐标系会自动对齐投影步骤甚至可以省略一部分。这里最能省时间的是把“拓扑修复”排除在脚本之外因为自动修复会误删区间出口悬挂点人工判断还是必要的脚本只处理确定性最高的投影和裁剪。交付后唯一要叮嘱使用者的是环境设置里那行outputCoordinateSystem 4549不要删。中游的干流和湖泊数据如果纬度跨了 3 度分带后期接 Bellhsh 流方向计算或坡度分析时不同投影会导致流域汇流路径偏移到时候再返工重投比第一遍做慢得多。本文还有配套的精品资源点击获取