一、背景

作为地形特征线的山脊线、山谷线对地形、地貌具有一定的控制作用。它们与山顶点、谷底点以及鞍部点等一起构成了地形起伏变化的骨架结构。同时由于山脊线具有分水性,山谷线具有合水性特征,使得它们在地形分析中具有特殊的意义。

二、目的

了解基于DEM水文分析方法提取山脊线和山谷线的原理;掌握水流方向、汇流累积量提取原理及方法。

三、要求

利用ArcGIS水文分析模块提取出样区的山脊线和山谷线。

四、数据

25m分辨率的DEM数据,区域面积约140km²(\ChP11 \Ex1目录中)。

五、算法思想

山脊线和山谷线的提取实质上也是分水线与汇水线的提取。因此,可以利用水文分析的方法进行提取。

对于山脊线而言,由于它同时也是分水线,而分水线的性质即为水流的起源点。所以,通过地表径流模拟计算之后,这些栅格的水流方向都应该只具有流出方向而不存在流入方向,即栅格的汇流累积量为零。因此,通过对零值的提取,就可得到分水线,即山脊线。

对于山谷线而言,可以利用反地形计算。即利用一个较大的数值减去原始DEM数据,得到与原始DEM地形相反的地形数据,使得原始的DEM中的山脊变成反地形的山谷,而原始DEM中的山谷在反地形中就变成了山脊。再利用山脊线的提取方法就可以实现山谷线的提取。但是此方法提取出的山脊和山谷位置有些偏差,可以利用正、负地形加以纠正。

流程图

六、模型构建器

七、ArcPy实现

# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------------
# 11-1 利用水文分析方法提取山脊线和山谷线.py
# Created on: 2021-10-11 10:09:40.00000
# (generated by ArcGIS/ModelBuilder)
# Description:
# --------------------------------------------------------------------------- # Import arcpy module
import arcpy
import os
import shutil
import time print time.asctime()
path = raw_input("请输入数据所在文件夹的绝对路径:").decode("utf-8")
# 开始计时
time_start = time.time()
paths = path + "\\result"
if not os.path.exists(paths):
os.mkdir(paths)
else:
shutil.rmtree(paths)
os.mkdir(paths) # Local variables:
dem = path + "\\dem"
Fill_dem = "Fill_dem"
Output_descent_rate_raster_zdx = "Descent_zdx"
FlowDir_zdx = "FlowDir_zdx"
FlowAcc_zdx = "FlowAcc_zdx"
FlowAcc0_zdx = "FlowAcc0_zdx"
Filter_zdx = "Filter_zdx"
threshold_zdx0_5541 = "thresh_zdx0"
meanDem = "meanDem"
Dem_Mean = "Dem_Mean"
zhengdixing = "zhengdixing"
sjx = "sjx"
Ridge_line = "山脊线"
minuend = "5000"
fu_fdx = "fu_fdx"
Abs_fdx = "Abs_fdx"
Output_descent_rate_raster_fdx = "Descent_fdx"
fudixing = "fudixing"
FlowDir_fdx = "FlowDir_fdx"
FlowAcc_fdx = "FlowAcc_fdx"
FlowAcc0_fdx = "FlowAcc0_fdx"
Filter_fdx = "Filter_fdx"
threshold_fdx0_65677 = "thresh_fdx0"
sgx = "sgx"
Valley_line = "山谷线"
Contour_dem = "Contour_dem"
HillSha_dem = "HillSha_dem" # Set Geoprocessing environments
print "Set Geoprocessing environments"
arcpy.env.scratchWorkspace = paths # 临时工作空间
arcpy.env.workspace = paths # 工作空间
arcpy.env.extent = dem # 处理范围
arcpy.env.cellSize = dem # 像元大小
arcpy.env.mask = dem # 掩膜 # Process: 填洼
print "Process: 填洼"
arcpy.gp.Fill_sa(dem, Fill_dem, "") # Process: 流向
print "Process: 流向"
arcpy.gp.FlowDirection_sa(Fill_dem, FlowDir_zdx, "NORMAL", Output_descent_rate_raster_zdx, "D8") # Process: 流量
print "Process: 流量"
arcpy.gp.FlowAccumulation_sa(FlowDir_zdx, FlowAcc_zdx, "", "FLOAT", "D8") # Process: 条件测试 (3)
print "Process: 条件测试 (3)"
arcpy.gp.Test_sa(FlowAcc_zdx, "value=0", FlowAcc0_zdx) # Process: 滤波器
print "Process: 滤波器"
arcpy.gp.Filter_sa(FlowAcc0_zdx, Filter_zdx, "LOW", "DATA") # Process: 条件测试 (4)
print "Process: 条件测试 (4)"
arcpy.gp.Test_sa(Filter_zdx, "value>0.5541", threshold_zdx0_5541) # Process: 焦点统计
print "Process: 焦点统计"
arcpy.gp.FocalStatistics_sa(dem, meanDem, "Rectangle 11 11 CELL", "MEAN", "DATA", "90") # Process: 减
print "Process: 减"
arcpy.gp.Minus_sa(dem, meanDem, Dem_Mean) # Process: 条件测试
print "Process: 条件测试"
arcpy.gp.Test_sa(Dem_Mean, "value>0", zhengdixing) # Process: 乘
print "Process: 乘"
arcpy.gp.Times_sa(threshold_zdx0_5541, zhengdixing, sjx) # Process: 重分类
print "Process: 重分类"
arcpy.gp.Reclassify_sa(sjx, "VALUE", "0 NODATA;1 1", Ridge_line, "DATA") # Process: 减 (2)
print "Process: 减 (2)"
arcpy.gp.Minus_sa(dem, minuend, fu_fdx) # Process: Abs
print "Process: Abs"
arcpy.gp.Abs_sa(fu_fdx, Abs_fdx) # Process: 流向 (2)
print "Process: 流向 (2)"
arcpy.gp.FlowDirection_sa(Abs_fdx, FlowDir_fdx, "NORMAL", Output_descent_rate_raster_fdx, "D8") # Process: 条件测试 (2)
print "Process: 条件测试 (2)"
arcpy.gp.Test_sa(Dem_Mean, "value<0", fudixing) # Process: 流量 (2)
print "Process: 流量 (2)"
arcpy.gp.FlowAccumulation_sa(FlowDir_fdx, FlowAcc_fdx, "", "FLOAT", "D8") # Process: 条件测试 (5)
print "Process: 条件测试 (5)"
arcpy.gp.Test_sa(FlowAcc_fdx, "value=0", FlowAcc0_fdx) # Process: 滤波器 (2)
print "Process: 滤波器 (2)"
arcpy.gp.Filter_sa(FlowAcc0_fdx, Filter_fdx, "LOW", "DATA") # Process: 条件测试 (6)
print "Process: 条件测试 (6)"
arcpy.gp.Test_sa(Filter_fdx, "value>0.65677", threshold_fdx0_65677) # Process: 乘 (2)
print "Process: 乘 (2)"
arcpy.gp.Times_sa(fudixing, threshold_fdx0_65677, sgx) # Process: 重分类 (2)
print "Process: 重分类 (2)"
arcpy.gp.Reclassify_sa(sgx, "VALUE", "0 NODATA;1 1", Valley_line, "DATA") # Process: 等值线
print "Process: 等值线"
arcpy.gp.Contour_sa(dem, Contour_dem, "50", "0", "1", "CONTOUR", "") # Process: 山体阴影
print "Process: 山体阴影"
arcpy.gp.HillShade_sa(dem, HillSha_dem, "315", "45", "NO_SHADOWS", "1") save = ["hillsha_dem", "contour_dem", u"山脊线", u"山谷线"]
rasters = arcpy.ListRasters()
for raster in rasters:
if raster.lower() not in save:
print u"正在删除{}图层".format(raster)
arcpy.Delete_management(raster)
# 结束计时
time_end = time.time()
# 计算所用时间
time_all = time_end - time_start
print time.asctime()
print "执行完毕!>>><<< 共耗时{:.0f}分{:.2f}秒".format(time_all // 60, time_all % 60)

八、结果







九、其它

在上实验课的时候,在老师那觅得相对上面,另一种更快捷的方式,而且也是比较通用,因为上面的那种方法,需要设置分界阈值,且的根据等值线和山体阴影来人工判断,而下面这种方法,虽然也是用水文分析方法,但不需要设置分界阈值,且对所有dem较为通用。

下面让我们来看看吧

模型构建器

跟上面的那种方法相比,主要省略了圈起来部分的步骤:

ArcPy实现

# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------------
# 11-1 利用水文分析方法提取山脊线和山谷线2.py
# Created on: 2021-10-11 10:47:48.00000
# (generated by ArcGIS/ModelBuilder)
# Description:
# --------------------------------------------------------------------------- # Import arcpy module
import arcpy
import os
import shutil
import time print time.asctime()
path = raw_input("请输入数据所在文件夹的绝对路径:").decode("utf-8")
# 开始计时
time_start = time.time()
paths = path + "\\result"
if not os.path.exists(paths):
os.mkdir(paths)
else:
shutil.rmtree(paths)
os.mkdir(paths) # Local variables:
dem = path + "\\dem"
Fill_dem = "Fill_dem"
Output_descent_rate_raster_zdx = "Descent_zdx"
meanDem = "meanDem"
Dem_Mean = "Dem_Mean"
zhengdixing = "zhengdixing"
FlowDir_zdx = "FlowDir_zdx"
FlowAcc_zdx = "FlowAcc_zdx"
FlowAcc0_zdx = "FlowAcc0_zdx"
sjx = "sjx"
Ridge_line = "山脊线"
minuend = "5000"
fu_fdx = "fu_fdx"
Abs_fdx = "Abs_fdx"
Output_descent_rate_raster_fdx = "Descent_fdx"
FlowDir_fdx = "FlowDir_fdx"
FlowAcc_fdx = "FlowAcc_fdx"
FlowAcc0_fdx = "FlowAcc0_fdx"
fudixing = "fudixing"
sgx = "sgx"
Valley_line = "山谷线" # Set Geoprocessing environments
print "Set Geoprocessing environments"
arcpy.env.scratchWorkspace = paths # 临时工作空间
arcpy.env.workspace = paths # 工作空间
arcpy.env.extent = dem # 处理范围
arcpy.env.cellSize = dem # 像元大小
arcpy.env.mask = dem # 掩膜 # Process: 填洼
print "Process: 填洼"
arcpy.gp.Fill_sa(dem, Fill_dem, "") # Process: 流向
print "Process: 流向"
arcpy.gp.FlowDirection_sa(Fill_dem, FlowDir_zdx, "NORMAL", Output_descent_rate_raster_zdx, "D8") # Process: 焦点统计
print "Process: 焦点统计"
arcpy.gp.FocalStatistics_sa(dem, meanDem, "Rectangle 11 11 CELL", "MEAN", "DATA", "90") # Process: 减
print "Process: 减"
arcpy.gp.Minus_sa(dem, meanDem, Dem_Mean) # Process: 条件测试
print "Process: 条件测试"
arcpy.gp.Test_sa(Dem_Mean, "value>0", zhengdixing) # Process: 流量
print "Process: 流量"
arcpy.gp.FlowAccumulation_sa(FlowDir_zdx, FlowAcc_zdx, "", "FLOAT", "D8") # Process: 条件测试 (3)
print "Process: 条件测试 (3)"
arcpy.gp.Test_sa(FlowAcc_zdx, "value=0", FlowAcc0_zdx) # Process: 乘
print "Process: 乘"
arcpy.gp.Times_sa(zhengdixing, FlowAcc0_zdx, sjx) # Process: 重分类
print "Process: 重分类"
arcpy.gp.Reclassify_sa(sjx, "VALUE", "0 NODATA;1 1", Ridge_line, "DATA") # Process: 减 (2)
print "Process: 减 (2)"
arcpy.gp.Minus_sa(dem, minuend, fu_fdx) # Process: Abs
print "Process: Abs"
arcpy.gp.Abs_sa(fu_fdx, Abs_fdx) # Process: 流向 (2)
print "Process: 流向 (2)"
arcpy.gp.FlowDirection_sa(Abs_fdx, FlowDir_fdx, "NORMAL", Output_descent_rate_raster_fdx, "D8") # Process: 流量 (2)
print "Process: 流量 (2)"
arcpy.gp.FlowAccumulation_sa(FlowDir_fdx, FlowAcc_fdx, "", "FLOAT", "D8") # Process: 条件测试 (5)
print "Process: 条件测试 (5)"
arcpy.gp.Test_sa(FlowAcc_fdx, "value=0", FlowAcc0_fdx) # Process: 条件测试 (2)
print "Process: 条件测试 (2)"
arcpy.gp.Test_sa(Dem_Mean, "value<0", fudixing) # Process: 乘 (2)
print "Process: 乘 (2)"
arcpy.gp.Times_sa(FlowAcc0_fdx, fudixing, sgx) # Process: 重分类 (2)
print "Process: 重分类 (2)"
arcpy.gp.Reclassify_sa(sgx, "VALUE", "0 NODATA;1 1", Valley_line, "DATA") save = [u"山脊线", u"山谷线"]
rasters = arcpy.ListRasters()
for raster in rasters:
if raster.lower() not in save:
print u"正在删除{}图层".format(raster)
arcpy.Delete_management(raster)
# 结束计时
time_end = time.time()
# 计算所用时间
time_all = time_end - time_start
print time.asctime()
print "执行完毕!>>><<< 共耗时{:.0f}分{:.2f}秒".format(time_all // 60, time_all % 60)

结果







感觉上述二者差别不是很大,但是第一种的分界阈值对不同dem数据,需要再做判断,而第二种不需要设置分界阈值,就很方便,所以,比较推荐第二种。

实验结束 byebye~~~

利用水文分析方法提取山脊线和山谷线(ArcPy实现)的更多相关文章

  1. 利用ArcGIS水文分析工具提取河网

    转自原文 利用ArcGIS水文分析工具提取河网(转) DEM包含有多种信息,ArcToolBox提供了利用DEM提取河网的方法,但是操作比较烦琐(帮助可参看Hydrologic analysis sa ...

  2. GIS案例学习笔记-水文分析河网提取地理建模

    GIS案例学习笔记-水文分析河网提取地理建模 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 目的:针对数字高程模型,通过水文分析,提取河网 操作时间:25分钟 数据 ...

  3. GIS与水文分析(1)GIS与水文学

    GIS与水文分析(1)GIS与水文学 对于大部分GIS从业人员或者利用GIS作为研究方向的人员来说,水文学过于专业,更偏重于理论化,很难从GIS的角度来模拟和分析水文的过程.这其实是个普遍性的问题,任 ...

  4. ArcGIS案例学习笔记4_2_水文分析批处理地理建模

    ArcGIS案例学习笔记4_2_水文分析批处理地理建模 联系方式:谢老师,135_4855_4328,xiexiaokui#139.com 概述 计划时间:第4天下午 目的:自动化,批量化,批处理,提 ...

  5. ArcGIS案例学习笔记4_1_水文分析

    ArcGIS案例学习笔记4_1_水文分析 联系方式:谢老师,135_4855_4328,xiexiaokui#139.com 概述 计划时间:第4天上午 教程: pdf page478 数据:实验数据 ...

  6. ArcGIS水文分析实战教程(15)库容和淹没区计算

    库容和淹没区计算 的基本流程 要计算库容就必须先计算出该集水区面积,并且通过不同的水位计算出淹没区,并利用淹没区去裁剪DEM数据,将水面与下垫面的体积计算出来,这就是水库的库容.由于有了前面的基础,这 ...

  7. Java安全之C3P0链利用与分析

    Java安全之C3P0链利用与分析 0x00 前言 在一些比较极端情况下,C3P0链的使用还是挺频繁的. 0x01 利用方式 利用方式 在C3P0中有三种利用方式 http base JNDI HEX ...

  8. Android APP性能分析方法及工具

    近期读到<Speed up your app>一文.这是一篇关于Android APP性能分析.优化的文章.在这篇文章中,作者介绍他的APP分析优化规则.使用的工具和方法.我觉得值得大家借 ...

  9. Linux下java进程CPU占用率高分析方法

    Linux下java进程CPU占用率高分析方法 在工作当中,肯定会遇到由代码所导致的高CPU耗用以及内存溢出的情况.这种情况发生时,我们怎么去找出原因并解决. 一般解决方法是通过top命令找出消耗资源 ...

随机推荐

  1. 使用ECharts绘制网址径向树状图

    an.rustfisher.com有很多内容,很多页面.如果用一个树状图把所有页面展示出来会是什么效果? 第一时间想到了ECharts. 最后效果: https://an.rustfisher.com ...

  2. vue 接入 vod-js-sdk-v6.js 完成视频上传

    东西有点多,耐心看完.按照操作一步一步来,绝对能成功 首先:npm 引入 npm install vod-js-sdk-v6 mian.js  全局引入  //腾讯云点播 import TcVod f ...

  3. K8S——Pod

    一.Pod概念 二.Pod存在的意义 三.Pod的实现机制 四.Pod镜像拉取策略 五.Pod资源限制 六.Pod重启机制 七.Pod的健康检查 八.Pod调度策略(创建Pod流程)

  4. Selenium系列(十七) - Web UI 自动化基础实战(4)

    如果你还想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识, ...

  5. JS020. Array map()函数查到需要的元素时跳出遍历循环,不再执行到数组边界

    Array.prototype.map() map( )  方法创建一个 新数组 *,其结果是该数组中的每个元素是调用一次提供的 函数后的返回值 *.[ MDN / RUNOOB ] * map 添加 ...

  6. 三剑客之awk 逐行读取

    目录: 一.awk工作原理 二.按行输出文本 三.按字段输出文本 四.通过管道,双引号调用shall命令 五.CPU使用率 六.使用awk 统计 httpd 访问日志中每个客户端IP的出现次数 一.a ...

  7. C++快读讲解

    C++快读讲解 inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') ...

  8. scrum项目冲刺_day02总结

    摘要:今日完成任务. 1.appUI页面完成 2.图像识别正在进行 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能 2.语音识别功能 3.垃圾搜索功能 4.相关新闻爬取 三. ...

  9. IDEA 集成 Docker 插件实现一键远程部署 SpringBoot 应用,无需三方依赖,开源微服务全栈项目有来商城云环境的部署方式

    一. 前言 最近有些童鞋对开源微服务商城项目 youlai-mall 如何部署到线上环境以及项目中 的Dockerfile 文件有疑问,所以写了这篇文章做个答疑以及演示完整的微服务项目发布到线上的流程 ...

  10. PHP方法参数的那点事儿

    在所有的编程语言中,方法或者函数,都可以传递一些参数进来进行业务逻辑的处理或者计算.这没什么可说的,但是在PHP中,方法的参数还有许多非常有意思的能力,下面我们就来说说这方面的内容. 引用参数 涉及到 ...