ArcGIS实战:岷江沱江流域地形图shp数据处理与地形分析全流程

📅 发布时间:2026/10/3 10:55:24
ArcGIS实战:岷江沱江流域地形图shp数据处理与地形分析全流程
简介这份资源面向GIS初学者、地理科研人员及水文流域研究者提供长江流域岷江、沱江水系的地形图与矢量数据可直接在ArcGIS中打开使用。压缩包共63个文件约42.74MB包含shp、dbf、prj、shx等矢量图层文件adf、nit、dat等栅格地形数据以及mxd工程文件、xml元数据和jpg、pdf、eps三种出图成果覆盖湖区、河流与90米DEM地形信息。对于不熟悉GIS操作的用户可直接使用已生成的流域地形图图片具备基础操作能力者则可通过mxd链接图层一键完成出图与区域调整。目前已有1352人学习下载适合用于流域分析、地形可视化、科研绘图与教学练习能帮助读者快速获取岷沱江水系的空间数据基础节省数据搜集与制图时间。1. 岷江沱江流域地形图 shp 拿到手之后先搞清楚它能干什么岷江和沱江是长江上游两条并行的水系岷江从松潘高原一路切到宜宾汇入长江沱江则从九顶山南麓穿过成都平原在泸州注入长江。把这两条水系连同它们的流域边界做成 shp 格式的矢量地形图本质上是在回答一个空间问题这片约 13 万平方公里的土地上分水岭在哪里、河网怎么分级、地形起伏跟水系发育是什么关系。很多人第一次拿到这类数据第一反应是拖进 ArcGIS 看个热闹结果发现属性表里字段看不懂、坐标系对不上、河流线跟流域面套不准。这篇东西就是把我自己处理岷江沱江流域 shp 的完整流程拆开讲——从数据检查、坐标系处理、地形因子提取到裁剪、拓扑修复和出图每一步都给出可复现的命令和参数。适合手里已经有或准备获取这套数据、需要在 ArcGIS 里做流域分析或专题制图的人新手能跟着走完熟手可以重点看避坑那章。2. 岷江沱江 shp 的数据构成与 ArcGIS 加载前的检查2.1 一套完整的流域地形图 shp 通常包含哪些图层流域地形图 shp 不是单个文件而是一组矢量图层的集合。以岷江沱江流域为例常见的图层构成如下表。拿到数据后先对照这张表清点缺哪个补哪个不要急着做分析。图层类型几何类型典型字段用途流域边界PolygonBASIN_NAME, AREA_KM2裁剪底图、统计面积河网水系LineSTRAHLER, LENGTH分级渲染、流向分析子流域分区PolygonSUB_ID, UP_AREA分区统计、水文建模地形等高线LineELEV, INDEX地形起伏表达高程点PointELEV, X, Y插值生成 DEM行政边界PolygonPROV, CITY叠加参考、出图标注岷江和沱江在宜宾—泸州一带交汇区域流域边界会有重叠或缝隙这是最常见的拓扑问题来源。清点时重点看流域边界和子流域分区这两个面图层它们决定了后续所有空间运算的准确性。2.2 用 ArcGIS 加载 shp 并检查坐标系与属性完整性加载 shp 本身很简单但加载之后必须做三件事确认坐标系、检查几何有效性、核对属性表。下面这段 Python 脚本基于 ArcPy可以在 ArcGIS Pro 或 ArcMap 的 Python 窗口里直接跑批量检查一个文件夹下所有 shp 的坐标系和几何状态。# -*- coding: utf-8 -*- import arcpy import os # 修改为你的 shp 文件夹路径 workspace rC:\data\minjiang_tuojiang arcpy.env.workspace workspace # 遍历所有 shp 文件 for shp in arcpy.ListFiles(*.shp): desc arcpy.Describe(shp) sr desc.spatialReference print(文件: {}.format(shp)) print( 几何类型: {}.format(desc.shapeType)) print( 坐标系: {} (WKID: {}).format(sr.name, sr.factoryCode)) # 检查几何有效性 check_result arcpy.CheckGeometry_management(shp, in_memory/check_ shp) with arcpy.da.SearchCursor(check_result, [PROBLEM]) as cursor: problems [row[0] for row in cursor] if problems: print( 几何问题: {}.format(set(problems))) else: print( 几何状态: 正常) # 统计要素数量 count int(arcpy.GetCount_management(shp).getOutput(0)) print( 要素数量: {}.format(count)) print(- * 40)这段脚本的逻辑是先通过Describe拿到每个 shp 的几何类型和坐标系 WKID再用CheckGeometry_management把几何问题写到一个临时表里最后用GetCount统计要素数。参数方面workspace改成你自己的路径即可in_memory是临时工作空间不会在磁盘上留垃圾文件。如果输出里出现 WKID 为 0 或 Unknown说明这个 shp 没有定义坐标系需要先补上再往下做。注意岷江沱江流域常用的坐标系是 CGCS2000 地理坐标系WKID 4490或 CGCS2000 3 度带投影如 WKID 4544 对应中央经线 102°E。如果拿到的是 WGS84WKID 4326面积和长度计算会有偏差必须先投影。2.3 属性表字段的读取与筛选逻辑属性表是 shp 的灵魂。以河网水系图层为例STRAHLER字段表示斯特拉勒分级值越小河流越大。用SearchCursor可以快速筛选出干流和一级支流import arcpy river_shp rC:\data\minjiang_tuojiang\river.shp # 筛选 Strahler 分级小于等于 3 的河流 with arcpy.da.SearchCursor(river_shp, [STRAHLER, LENGTH, SHAPELENGTH]) as cursor: for row in cursor: strahler row[0] length_attr row[1] length_geom row[2] if strahler is not None and strahler 3: # 对比属性长度和几何长度差异过大说明投影有问题 if abs(length_attr - length_geom) 100: print(长度异常: Strahler{}, 属性长度{:.1f}, 几何长度{:.1f}.format( strahler, length_attr, length_geom))这里的关键参数是SHAPELENGTH它返回几何的实际长度单位取决于坐标系。如果属性表里的LENGTH字段和几何长度差了一个数量级大概率是地理坐标系下计算的结果需要投影后再重新计算。这个检查在岷江这种跨度大的流域尤其重要因为经度方向一度对应的实际距离在高纬度会明显缩短。3. 在 ArcGIS 里把岷江沱江 shp 用起来裁剪、投影与地形因子提取3.1 用流域边界裁剪河网与等高线拿到全流域的河网和等高线后第一步通常是按流域边界裁剪去掉流域外的部分。ArcGIS 里用Clip工具但参数设置有讲究。下面用 ArcPy 演示import arcpy arcpy.env.workspace rC:\data\minjiang_tuojiang arcpy.env.overwriteOutput True # 输入河网线图层、流域边界面图层 river river.shp basin basin_boundary.shp out_river river_clipped.shp # 裁剪注意 cluster_tolerance 参数 arcpy.Clip_analysis(river, basin, out_river, cluster_tolerance0.001 Meters) print(裁剪完成输出: {}.format(out_river))Clip_analysis的第四个参数cluster_tolerance控制裁剪时的容差。对于岷江沱江这种地形复杂的区域如果容差设得太大河流线在边界处会出现明显的锯齿或断裂设得太小又可能导致裁剪失败。我一般先用默认值跑一遍如果边界处有毛刺再调到 0.001 米重新跑。裁剪完成后用GetCount对比裁剪前后的要素数如果裁剪后要素数反而变多说明河网在边界处被切成了很多碎线需要后续用UnsplitLine合并。提示等高线裁剪后经常出现短小碎线可以在属性表里按SHAPELENGTH排序删掉长度小于 50 米的线段这些碎线在出图时基本看不见但会拖慢渲染速度。3.2 坐标系转换从地理坐标到投影坐标的完整操作岷江沱江流域跨了多个 3 度带如果要做面积和长度统计必须统一到一个投影坐标系。常见做法是选中央经线 102°E 或 105°E 的 CGCS2000 3 度带。在 ArcGIS 里用Project工具import arcpy arcpy.env.workspace rC:\data\minjiang_tuojiang arcpy.env.overwriteOutput True input_shp river_clipped.shp # CGCS2000 3 度带 中央经线 102°E 对应的 WKID 是 4544 out_coordinate_system arcpy.SpatialReference(4544) output_shp river_projected.shp arcpy.Project_management(input_shp, output_shp, out_coordinate_system) print(投影完成: {}.format(output_shp))Project_management的第三个参数可以直接传SpatialReference对象也可以传 .prj 文件路径。WKID 4544 对应的是 CGCS2000 3 度带第 34 带中央经线 102°E适合岷江上游和沱江大部分区域。如果数据延伸到 105°E 以东可以改用 WKID 4545中央经线 105°E。投影之后再用CalculateGeometryAttributes重新计算面积和长度字段确保属性表里的数值和几何一致。3.3 从等高线和高程点生成 DEM 并提取坡度坡向地形图 shp 里的等高线和高程点是生成 DEM 的原料。ArcGIS 里用Topo to Raster工具它比IDW或Kriging更适合等高线数据因为能保证等高线不被穿越。操作步骤如下第一步把等高线和高程点放在同一个要素数据集里确保坐标系一致。第二步在 ArcToolbox 里找到Spatial Analyst Tools Interpolation Topo to Raster。第三步输入要素选等高线字段选ELEV和高程点字段选ELEV输出像元大小根据数据精度定岷江沱江流域一般用 30 米。第四步Drainage Enforcement选Enforce这样生成的 DEM 会尊重河网位置不会出现河流倒流。import arcpy from arcpy.sa import * arcpy.CheckOutExtension(Spatial) arcpy.env.workspace rC:\data\minjiang_tuojiang arcpy.env.overwriteOutput True # 输入要素等高线和高程点 contour contour.shp spot spot_height.shp out_dem dem_30m # Topo to Raster 参数 arcpy.TopoToRaster_3d( in_features[[contour.shp, ELEV], [spot_height.shp, ELEV]], out_surface_rasterout_dem, cell_size30, extentbasin_boundary.shp, margin10, minimum_z_value200, maximum_z_value6000, drainage_enforcementENFORCE, profile_penalty40, stream_penalty0.5 ) print(DEM 生成完成: {}.format(out_dem))参数说明cell_size30对应 30 米分辨率extent限定在流域边界内minimum_z_value和maximum_z_value根据岷江沱江实际高程范围设定岷江源头雪宝顶海拔约 5588 米沱江下游河口约 200 米所以设 200 到 6000 是合理的drainage_enforcementENFORCE强制 DEM 与河网一致profile_penalty和stream_penalty控制地形平滑度和河流下切程度默认值通常够用如果生成的 DEM 在河谷处过于平坦可以把stream_penalty调到 0.8 左右。DEM 生成后用Slope和Aspect工具提取坡度和坡向from arcpy.sa import Slope, Aspect dem dem_30m slope Slope(dem, DEGREE) slope.save(slope_degree) aspect Aspect(dem) aspect.save(aspect) print(坡度坡向提取完成)坡度输出用DEGREE单位范围 0 到 90 度。坡向输出 0 到 360 度正北为 0顺时针增加。这两个栅格可以进一步和河网叠加分析河流走向与坡向的关系。4. 岷江沱江 shp 处理中的避坑与排查4.1 坐标系不一致导致裁剪结果为空现象用流域边界裁剪河网输出图层要素数为 0或者裁剪结果跑到几千公里外。原因两个图层的坐标系虽然都显示为 CGCS2000但一个是地理坐标系度一个是投影坐标系米ArcGIS 在裁剪时不会自动转换而是按数值直接运算。解决先用Project把两个图层统一到同一个投影坐标系再执行裁剪。检查方法是右键图层属性看Source里的Spatial Reference是否完全一致包括 WKID 和单位。4.2 几何无效导致空间分析报错现象运行Intersect或Union时提示「几何无效」或「拓扑错误」。原因shp 格式本身不支持真正的拓扑面图层容易出现自相交、缝隙、重叠。岷江沱江流域边界在宜宾附近有多条支流汇入边界线容易打结。解决用RepairGeometry工具修复或者用CheckGeometry先定位问题要素。修复后再跑一次CheckGeometry确认。如果修复后仍有问题把问题要素导出到新 shp手动编辑节点。import arcpy arcpy.RepairGeometry_management(basin_boundary.shp) print(几何修复完成)4.3 属性表中文乱码现象属性表里的BASIN_NAME字段显示为乱码。原因shp 的 .dbf 文件默认编码是系统区域设置如果数据来自不同环境中文可能被错误解码。解决在 ArcGIS Pro 里可以用AlterField修改字段但更稳妥的方法是用 Python 的dbfread库读取后重新写入。或者在 ArcMap 里通过Table to Table转换时指定编码。我一般会在拿到数据后先导出为 File Geodatabase 格式GDB 对中文支持更稳定。4.4 裁剪后河流线断裂现象裁剪后的河网在流域边界处变成很多短线段无法做流向分析。原因Clip工具会把跨越边界的线在边界处切断。解决用UnsplitLine工具按河流名称或 ID 合并或者改用Intersect工具并设置output_type为LINE。如果河流没有唯一 ID可以先用Dissolve按STRAHLER字段合并但这样会丢失单条河流的独立性。4.5 投影后面积字段未更新现象投影之后属性表里的AREA_KM2字段还是旧值和几何面积对不上。原因Project工具只改变几何坐标不会自动重算属性字段。解决用CalculateGeometryAttributes重新计算面积和长度字段。注意单位选择投影坐标系下面积单位选SQUARE_KILOMETERS长度选KILOMETERS。import arcpy arcpy.CalculateGeometryAttributes_management( basin_projected.shp, [[AREA_KM2, AREA], [PERIM_KM, PERIMETER]], area_unitSQUARE_KILOMETERS, length_unitKILOMETERS ) print(面积和周长字段已更新)5. 把岷江沱江 shp 做成可复用的地形分析模板5.1 用模型构建器固化处理流程每次拿到新的流域 shp 都手动跑一遍工具太累ArcGIS 的模型构建器可以把上面这些步骤串起来。在 ArcMap 或 ArcGIS Pro 里打开ModelBuilder依次拖入Project、Clip、TopoToRaster、Slope、CalculateGeometryAttributes用连接线把输出连到下一个工具的输入。关键是把坐标系 WKID、像元大小、裁剪容差这些参数暴露为模型参数这样换一个流域只需要改参数不用重新搭流程。模型保存为.tbx工具箱以后直接双击运行。5.2 批量处理多个子流域的脚本写法岷江沱江流域可以进一步分成多个子流域如果每个子流域都要单独出图用循环批量处理更高效。下面这段脚本遍历子流域面图层逐个裁剪 DEM 并计算平均坡度import arcpy from arcpy.sa import * import os arcpy.CheckOutExtension(Spatial) arcpy.env.workspace rC:\data\minjiang_tuojiang arcpy.env.overwriteOutput True sub_basins sub_basin.shp dem dem_30m slope slope_degree out_folder rC:\data\minjiang_tuojiang\sub_output if not os.path.exists(out_folder): os.makedirs(out_folder) # 遍历每个子流域 with arcpy.da.SearchCursor(sub_basins, [SUB_ID, SHAPE]) as cursor: for row in cursor: sub_id row[0] geom row[1] # 用子流域几何裁剪 DEM dem_clip ExtractByMask(dem, geom) dem_clip.save(os.path.join(out_folder, dem_sub_{}.tif.format(sub_id))) # 裁剪坡度并计算平均值 slope_clip ExtractByMask(slope, geom) mean_slope arcpy.GetRasterProperties_management(slope_clip, MEAN) print(子流域 {}: 平均坡度 {:.2f} 度.format(sub_id, float(mean_slope.getOutput(0))))这段脚本的核心是ExtractByMask它按几何范围裁剪栅格。SUB_ID是子流域的唯一标识用来命名输出文件。GetRasterProperties_management的MEAN参数返回栅格平均值。跑完之后每个子流域的 DEM 和平均坡度就都有了可以直接拿去做水文分析或制图。5.3 出图时的符号化与标注技巧最后一步是出图。河网用STRAHLER字段做分级渲染值越小线越粗。流域边界用空心填充加粗边框。等高线只显示计曲线INDEX字段为 1 的首曲线太密会糊成一片。标注用Maplex引擎河流名称沿河流方向放置流域名称放在面中心。出图分辨率至少 300 dpi岷江沱江流域全图用 A1 幅面比较合适。我自己的习惯是每次处理完一套流域 shp都会把坐标系、投影参数、裁剪容差、DEM 像元大小这几个值记在一个文本文件里下次换流域直接改这几个数。这套流程在岷江沱江上跑通之后换成嘉陵江或乌江基本只需要改 WKID 和裁剪范围。希望帮到你。本文还有配套的精品资源点击获取