ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

洞庭湖水系shp在ArcGIS中的使用:坐标系与几何修复避坑指南

洞庭湖水系shp在ArcGIS中的使用:坐标系与几何修复避坑指南 简介这是一份面向ArcGIS用户的长江流域洞庭湖水系地形图数据包内含湖泊、河网等shp格式矢量文件及配套地形栅格适用于流域制图、空间分析与科研展示。包内共61个文件除shp、dbf、prj等基础矢量文件外还提供mxd地图工程、DEM栅格及出图成果整体约64.93MB结构清晰便于按需调用。针对不同技能层级的用户既可通过mxd一键挂接图层快速出图也可直接使用随包生成的JPEG、PDF、EPS格式图片无需GIS操作即可获取流域地形底图。目前已有2573人学习下载适合地理信息相关专业学生、科研人员及需要洞庭湖流域底图的项目开发者参考使用。需注意数据经网络搜集加工使用前请自行核验精度与时效性。1. 长江流域洞庭湖水系流域地形图shp一个让ArcGIS新手最易翻车的流域数据接到一个需要用到长江流域洞庭湖水系流域地形图shp格式矢量文件的项目时第一反应通常是“去网上下个shp拖进ArcGIS就能用”——这个想法会在半小时后让你怀疑人生。写着“流域地形图”的数据拿到手往往不是一个shp文件而是一个文件夹里的一组矢量文件流域边界、子流域面、水系线、湖泊面、等高线有时还夹着一个DEM栅格。真正的工程量不在“下载”这一步而在打开前的检查、坐标系确认、几何修复和编码处理。这篇笔记就是给那些拿到洞庭湖流域数据之后想把shp在ArcGIS里稳稳用起来的人水利规划、环评、流域治理、土地整理项目都适用新手能照着做完老手也能在投影选型和避坑清单里找到几个平时容易忽略的细节。2. 先看再动手洞庭湖shp矢量文件的数据结构与拿到手的三项检查2.1 流域地形图shp的构成一个图层对应一个文件夹不是“一个文件”先说一个新手最容易懵的点shp格式矢量文件从来不是一个单独的文件。ESRI Shapefile是一组文件的集合至少包含三个核心文件.shp主文件存放几何坐标和要素类型.shx索引文件存放几何在文件中的位置索引.dbf属性表存放与几何一一对应的属性字段除此之外还常见到.prj投影信息、.sbn/.sbx空间索引、.xml元数据。不少人从网盘或邮箱里拷贝数据时只复制了一个.shp文件拖进ArcMap后图形一片空白或者只能看到属性表却看不到图形就是这个原因。拷贝整套数据时最稳妥的做法是整个文件夹一起拷。拿到一份洞庭湖水系地形图常见的图层清单是这几类图层几何类型常见属性字段用途流域边界polygon名称、面积、代码全流域范围统计与出图子流域边界polygon子流域名称、干流编号分区统计、嵌套分析水系线polyline河名、河流级别、河长河网渲染、长度统计湖泊与坑塘polygon湖名、面积湖区蓄滞洪分析等高线polyline高程值地形表达、坡度参考这里的关键是先打开文件夹目录看一眼确认手上是“完整数据”还是“缩略数据”。很多第三方提供的shp只有干流水系没有子流域面或者给了一个全流域大边界但内部没有分区。后续要做分割、统计、嵌套出流点分析时才发现缺数据再回去找联系人补项目周期就被拖住了。我拿到数据后的固定动作是先列文件清单缺了哪个文件直接邮件沟通不带着残缺数据往下做。2.2 打开项目前先跑一遍检查脚本投影、几何、字段三位一体不要急着把shp拖进ArcMap。先建一个干净的工作目录把shp及配套文件统一放好然后做三件事看.prj文件在不在、打开ArcCatalog右键查看坐标系、用修复几何工具跑一遍。我一般更喜欢在ArcGIS的Python窗口里直接跑一段arcpy脚本做批量检查这样一套流程下来所有shp的状态都有文字记录比在界面里一个个右键查属性直观得多import arcpy import os # 改成你的shp所在文件夹路径 ws rD:\Dongting_shp arcpy.env.workspace ws for shp in arcpy.ListFeatureClasses(): desc arcpy.Describe(shp) # 逐个打印名称、类型、坐标系名称、要素数 print(文件:{} 类型:{}.format(shp, desc.shapeType)) print(坐标系:{}.format(desc.spatialReference.name)) print(要素数量:{}.format(arcpy.GetCount_management(shp)[0])) # 修复几何错误清理自相交、空几何 try: arcpy.RepairGeometry_management(shp) print(几何修复完成) except Exception as e: print(修复出错:, e)这段脚本的逻辑是用arcpy.ListFeatureClasses()遍历工作目录下所有矢量要素类再通过arcpy.Describe读取每个shp的类型、坐标系、要素数量最后用RepairGeometry_management对几何做一次自愈。需要注意三个关键输出——坐标系名称是WGS_1984、CGCS2000还是“Unknown”要素数量是否合理流域水系线shp如果只有几十条线多半是精简版数据几何修复是否报错报错说明原始数据存在严重的拓扑问题。注意脚本一定要在ArcGIS自带Python窗口运行ArcMap和ArcGIS Pro的Python环境都行但不要用外部独立的Python解释器跑会直接报“arcpy模块找不到”。另外很多初学者问ArcGIS Pro里是不是自带pandasarcpy本身不依赖pandas如果你要在Pro里做属性表分析需要另外用conda装pandas。如果数据质量要求更高比如要给规划审查用可以在修复几何之后再跑一次Check Geometry工具它能把“空几何”“自相交”“重复节点”“尖角”这类问题分类列出来。尖锐角在ArcGIS里没有一键修复的通用插件常见做法是用Check Geometry工具输出问题要素逐个在编辑会话里手动处理——这个动作虽然原始但也是能让数据经得起审查的最可靠方式。3. 坐标系决定一切把洞庭湖shp在ArcGIS里用对的投影策略3.1 地理坐标系还是投影坐标系为什么shp在ArcMap里会“飞到西伯利亚”把shp拖进ArcMap后图形跑到了地图边缘或者和底图完全对不上十有八九是坐标系信息缺失或定义错了。shp如果没有带.prj文件ArcMap默认把它当成“未知坐标系”处理叠加时按无投影方式绘制自然和在线底图错位。常见做法是右键图层–属性–源查看空间参考信息。如果是“Unknown”或空值右键要素类–属性–编辑–定义投影把它设成GCS_CGCS2000或GCS_WGS_1984。这里有个容易混淆的点定义投影Define Projection只是给数据贴上坐标系的标签不改变任何坐标数值投影变换Project才是把几何坐标从一套系统换算到另一套。很多新手把Project工具当成“给数据设坐标系”用结果数据被转了两次位置错得更离谱。判断一个没有投影信息的shp大概是什么坐标系有个土办法看属性表里某个要素的X、Y坐标值。如果X接近六个位数、Y接近四个位数比如X510000Y3300000大概率是高斯克吕格投影下的平面坐标。如果X、Y都是八位数和七位数X前面还带带号如37开头那就是加了带号的高斯克吕格坐标。有了这个判断定义投影时就能少走弯路。3.2 经纬度、高斯克吕格、阿尔伯斯三个投影如何选参数怎么设洞庭湖水系横跨湘、资、沅、澧四水东西跨度大南北纬度差也大。在不同用途下坐标系选择不一样参数也不一样用途坐标系适合场景参数要点底图叠加、数据交换GCS_CGCS2000与在线地图、GPS采集数据叠加无需投影参数直接用经纬度面积、长度量测CGCS2000 / 3-degree Gauss-Kruger单一支流流域、局部工程区中央经线取111E–114E按工程区位置选带全流域面积统计、专题出图CGCS2000 / Albers洞庭湖全流域面状统计双标准纬线25°N与47°N中央经线105°E在ArcGIS里做投影转换的路径是ArcToolbox–Data Management Tools–Projections and Transformations–Feature–Project。输入原始shp输出坐标系选上面表格里的目标坐标系工具会生成一个新的shp文件。我习惯把原始数据保留一份不动投影转换生成的成果放到另一个目录这样万一选错投影还有后悔药。为什么不建议直接用WGS84经纬度算面积因为经纬度坐标下的面积单位是“度”不是平方米。虽然ArcGIS的字段计算器里有shape.geodesicArea这类高精度表达式能在一定程度上绕开投影问题但涉及多个图层叠加、拓扑分析、缓冲区计算时平面投影坐标系依然是更稳的选择。平面坐标系的另一个好处是跟工程设计单位对接时他们拿到的通常是高斯克吕格坐标的图纸两边坐标系一致才能直接套图。3.3 shp和地形底图对不上用空间校正还是地理配准拿到洞庭湖shp经常还要叠加扫描版地形图、天地图影像或者PDF图纸。如果发现矢量水系和影像上的河道位置整体偏了先判断是谁偏了。影像底图错位用ArcMap的Georeferencing工具校正栅格在影像上找4到6个特征点最好选河流拐弯、湖泊角点、桥梁这些不易混淆的位置逐一点选对应到矢量shp的正确坐标做一阶多项式变换。控制点越分散越好全都挤在屏幕一角校正完另一角还是歪的。矢量shp整体偏移用Spatial Adjustment工具做仿射变换。常见的情形是第三方给的水系shp用的是西安80坐标系你的底图是CGCS2000两者在洞庭湖区域会存在几十米到上百米的系统性偏差。做法是在编辑会话里加载Spatial Adjustment工具条先设置校正数据为这个shp再选择“仿射”变换方式找几个控制点链接执行校正。相比硬套Project工具这种基于同名点配准的方式在原始数据没有正确投影信息时更实用。我刚入行时不知道有Spatial Adjustment遇到几个图层整体东移三百米在编辑会话里一个个挪要素挪到凌晨两点。后来发现空间校正十秒钟能解决同一类问题。那个夜晚给我留下两条教训第一坐标系和投影问题一定要在数据处理链路的起点解决第二遇到整体偏移先找工具不要硬改几何。4. 从DEM和矢量数据里自己产出流域shp提取河网、子流域与属性字段计算4.1 没有现成流域边界用DEM的Hydrology工具自己提取一份很多项目拿到的shp里没有流域边界只有一段干流河线。这种情况下常见做法是下载公开的DEM数据SRTM或ALOS这类直接在ArcGIS里用水文分析工具把流域边界和河网提取出来。这个过程是Spatial Analyst扩展模块里的Hydrology工具集核心流程四步第一步填洼Fill。DEM里天然存在一些凹陷像元如果不填平水流会困在坑里影响后续流向计算。Z limit参数默认空着表示全部填满在山地地形可以直接默认在洞庭湖平原湖区DEM噪声大Z limit建议设到5到10米一次填不干净就填两次。第二步流向Flow Direction。基于D8算法计算每个像元的水流方向输出一个方向栅格。这个栅格后续要用两遍所以一定要保留。第三步汇流累积量Flow Accumulation。数学意义是每个像元上游有多少个像元的水流汇入数值越大代表越靠近主河道。第四步栅格计算器里用Con工具提取河网Con(flowacc 阈值, 1)把汇流累积量超过阈值的像元设为1其余设为空值。这个阈值是整个流程里最“玄学”的参数。在湘西山区地形起伏大汇流路径清楚阈值取1000到3000就能出来理想的河网在洞庭湖湖区地势平缓同样阈值提取出来全是碎线需要把阈值提到5000到10000。判断标准很简单出图的河网密度符合你对“干流主要支流”的预期就行多试几次每次用不同阈值对比效果。最后用Stream to Feature工具把栅格河网转成polyline shp。输出的shp就是可直接用于ArcGIS的河网矢量文件。4.2 用分水岭工具生成子流域边界shp河网提出来还不够规划项目里通常需要知道湘江、资水、沅江、澧水各自的子流域范围。用Watershed工具可以实现输入流向栅格再输入一个出流点pour point栅格工具会计算该点以上的所有汇水区域输出子流域栅格再用Raster to Polygon转成polygon shp。没有现成出流点的情况下可以通过栅格计算器对汇流累积量栅格设阈值来生成自动出流点先把达到河流阈值的像元设为1再转到矢量点然后在河口位置手动挑一个点作为出流点。这个做法业内叫“自动出流点”对于自动化批处理多个子流域很省事。有一个常被忽略的参数输出子流域栅格前最好对流向栅格做一次“条件过滤”把平原湖区的平坦像元先处理掉否则分水岭边界会出现大量锯齿状碎边。处理方式是用Focal Statistics工具对流向栅格做一次3×3众数滤波再作为Watershed的输入。4.3 把shp属性表用满面积、河网长度、比降字段一次算清流域规划里最常用的三个计算流域面积、河网总长度、河流比降。这些都可以直接在shp属性表里算出来不依赖外部表格。面积字段的计算方法是新建一个双精度字段area_km2右键字段打开字段计算器在表达式里写入Python表达式!shape.geodesicAreaSQUAREKILOMETERS!。这个表达式的意义是直接调用几何对象的大地测量面积接口结果单位是平方千米它比!shape.area!更接近真实地表面积因为后者在经纬度坐标系下返回的是球面度量纲不对。字段计算器支持Python解析器时用上面的写法如果只能用VBScript就退而求其次用!shape.area!但务必先把数据投影到平面坐标系再计算。河网长度同理对polyline要素新建len_km字段用!shape.lengthKILOMETERS!。河流比降需要河段起止点的高程字段先按上游到下游对河段排序用!ELEV_start! - !ELEV_end!得到落差再除以len_km得到每公里的坡降单位是米每千米。如果shp属性表里没有起止点高程可以用Extract Values to Points工具从DEM上把高程采样到河流的起点和终点。这里有一个我在报告里反复备注给同事的坑!shape.area!在WGS84经纬度坐标系下返回的不是平方米也不是平方千米而是一个无意义的平方度数值直接填进报告里当平方公里用面积能差出去十倍以上。所有面积和长度字段必须在投影后计算并在字段别名里写明坐标系和单位。4.4 接入水文站观测数据把Excel里的流量、水位挂到shp站点的做法流域分析离不开实测水文数据。手头通常是一张Excel表里面有站点名称、经纬度、多年平均流量、水位等字段。把Excel挂到shp上的标准流程是先把Excel另存为csv编码问题见下文在ArcMap里右键–Add XY Data按站点经纬度生成事件图层再导出成shp站点文件。然后用右键–Joins and Relates–Join把csv表和shp属性表按“站点编码”字段做一对一关联。关联的关键是字段类型和值要完全一致。csv里的站点编码如果存成了文本shp属性表里也要是文本数值格式的“4302”和文本格式的“4302”在关联时会被当成不同值。常见做法是在导入csv前先检查Excel里这一列的格式统一设为文本避免科学计数法把编码变成“4.30E02”。csv中文乱码是这个流程里最高频的翻车点。Excel另存为csv时默认可能是ANSI编码也可能是UTF-8带BOM取决于Excel版本。ArcMap 10.x对UTF-8 csv的兼容性不如ArcGIS Pro读出来中文字段名显示乱码的概率很高。我的做法是文本编辑器打开csv确认编码必要时另存为GBK编码再导入ArcMap如果在ArcGIS Pro里操作用UTF-8反而更稳。这个问题没有一劳永逸的解法多备两个编码版本哪个能读用哪个。5. 避坑与排查洞庭湖shp在ArcGIS里翻车的五个血泪现场5.1 坐标系字段消失同样的shp别人能叠加我却找不到坐标现象打开定义投影工具输入shp后工具直接报“未定义坐标系”或者地图上图形位置全部在赤道附近的海里和实际位置差了十万八千里。原因数据从第三方拷贝过来时.prj文件被漏掉或重命名时被忽略。还有一种情况数据早期在别的GIS软件里定义过坐标系但导出shp时没有勾选写入投影信息导致shp头文件里缺失坐标系标签。解决先检查目录里有没有.prj、.aux.xml、.xml这些投影相关文件。都没有的话打开shp属性表看几个要素的坐标值如果X是七位数且以37开头Y是七位数通常是CGCS2000或西安80的高斯克吕格37带坐标如果X是六位数不带带号则是3度带的高斯克吕格中央经线坐标。基于这个判断用定义投影工具补上坐标系即可。如果完全无头绪找同区域已知坐标的参考点用Spatial Adjustment做校正。5.2 修复几何让要素变得“缺一块”Repair Geometry也要分清场景现象对洞庭湖湖泊面polygon执行Repair Geometry后原本闭合的湖岸线出现锯齿或者湖面面积明显缩小看起来像被工具“切掉一块”。原因Repair Geometry会把自相交环、重叠环、重复节点做拓扑重建。如果原始数据多个环没有正确拆分工具按自交边界重建外环时可能把一部分有效湖面排除在外。解决执行修复前先备份原始shp。修复后对比前后面积变化超过5%就说明原数据本身拓扑质量问题很大不能依赖自动修复而是要对原始数据重新配准或重新数字化。兄弟单位给过一份洞庭湖湖泊面shp一修复面积缩了三分之一后来查明多个湖泊环没拆开修复工具自动合并了外环——这种数据只能重建不能修。5.3 ArcMap里dbf字段只显示前三个汉字中文属性表乱码的根因现象打开水文站点shp的属性表站点名字段显示“城陵”或“沅江”完整名称“城陵矶”“沅江市”显示不全某些字段直接显示问号。原因shp的dbf属性表在创建时带有编码标记ArcMap按系统本地语言读dbf。如果原始dbf是UTF-8编码在中文Windows上被按GBK解码就会出现截断或乱码。这个问题和csv乱码是同一类根源——数据生产工具不同编码约定不统一。解决ArcMap里直接改dbf编码比较绕最稳妥的做法是用ArcToolbox里的Table To DBASE工具把属性表重新导出一次导出时选择文本编码类型或者把字段内容用字段计算器重新赋值一遍让ArcMap按当前语言环境重写。更彻底的办法是规范数据入库在数据生产环节统一约定编码为UTF-8ArcGIS Pro能直接正确读取而ArcMap 10.x用户继续用GBK。团队协作时各人软件环境不一致这个约定必须写进项目文档。5.4 提取河网shp出来全是碎线头DEM填洼没做扎实现象用水文分析工具提取洞庭湖平原区的河网出来的shp全是断线、碎屑线段主干河网上挂着大量毛刺看起来像一张破渔网。原因平原地带地形极其平缓DEM的高程误差直接导致流向计算方向随机化汇流累积量在平地上形成平行线噪声阈值分割后就成了断线碎线。这不是提取工具的问题是DEM预处理没有做扎实。解决填洼Fill时把Z limit从默认值提高到5到10米填完一遍再跑第二遍Fill确保平地上没有残余凹陷。代价是填洼力度大会填掉真实存在的微小地形特征所以出图时要对比原DEM和填洼后DEM的等高线确认没有抹掉关键河道。另一个有效手段是先对DEM做一次Focal Statistics均值滤波3×3窗口平滑两次再跑流向累积。亲测同样阈值下平滑后的河网线型干净一半以上。5.5 ArcMap启动许可没反应License Manager服务不是摆设现象双击ArcMap没反应或闪退启动界面长时间停在“正在启动许可”然后消失。原因安装ArcGIS后License Manager服务没有自动启动或者服务启动失败、许可文件失效。杀毒软件拦截License Manager服务也是常见诱因尤其是10.8安装包在老机器上更容易遇到。解决控制面板–管理工具–服务找到ArcGIS License Manager确认状态是“正在运行”如果没运行手动启动并把启动类型设为“自动”。再用License Server Administrator查看许可状态如果显示被占用或无效选择“重新读取许可文件”刷新。升级到ArcGIS 10.8时建议先卸载旧License Manager服务、重启机器、再装新版本这是ArcGIS安装老手的基本流程不按这个顺序走容易在启动时翻车。提示遇到许可启动无响应先看系统服务再看License状态最后怀疑杀毒软件不要一上来就重装软件。6. 让shp真正出彩四至范围、动态Excel表格与WKT导出的三个进阶技巧6.1 四至范围坐标一次性算出来多图层出图不再手抄出图时图框外要标“四至范围”传统做法是右键图层属性–源抄四个角点的坐标然后再手工填到图例里。这个动作在批量出图时极其容易抄错。字段计算器可以一步把每个要素的XMin、YMin、XMax、YMax拼接成文本写进属性表# 在字段计算器中使用Python表达式 # 新建字符串字段存四至范围文本 !shape.extent.XMin! , !shape.extent.YMin! , !shape.extent.XMax! , !shape.extent.YMax!如果是整个流域只需一个总范围不用新建字段直接在数据框属性里设置显示“四至范围”即可。多个子流域图层要分别出图时字段计算器这种方式能批量产出每个子流域的坐标配合数据驱动页面按字段出图效率提升明显。6.2 批量出图时把Excel表格稳插到图框的固定位置动态表格的新思路地图里要附带水文站点统计表传统做法是在布局视图里插入Excel对象但批量出图时这个对象经常错位、不随页面刷新。我的土办法是把表格转成矢量要素先把Excel另存为csv导入ArcGIS用Create Fishnet生成一个足够密的矩形格子把表格的行按顺序填进Fishnet的属性字段再给Fishnet配一个表格样式的符号。这样出来的“表格”是shp图层跟着数据框走位置稳定永不刷新错位这是替代自带的Excel对象最省心的方式。6.3 shp导出为WKT给外业App和写代码的同事用外业采集App和web端开发经常只要WKT字符串不要shp。ArcGIS的Python窗口里可以直接把shp要素输出为WKTimport arcpy shp rD:\Dongting_shp\river.shp with arcpy.da.SearchCursor(shp, [SHAPE]) as cursor: for row in cursor: print(row[0].WKT)这段脚本用arcpy.da.SearchCursor逐行读取要素row[0]是几何对象调用.WKT属性即可得到要素的WKT文本。如果shp里是几百条河段建议先筛选需要的要素再导出或直接把print改成写文件避免Python窗口被刷屏。带Z值的复杂线要素外业那边解析可能会有问题导出前先用Feature to 2D转成二维要素再转WKT。这三招做完洞庭湖流域shp在项目里基本就吃得开了。坦白说我刚接触shp那会也不知道有shape.extent这种捷径四至范围是一个一个坐标手抄的抄错一个数就要返工一张图。后来养成一个习惯所有外来的shp第一件事永远是“看坐标系、修几何、查字段编码”这三样确认过后面才能放心叠加、计算和出图。希望这些踩坑和技巧能帮到你。本文还有配套的精品资源点击获取
返回列表