采用的是Windows窗体应用,本文仅提供主体代码。
算法思想:
1、读取数据,并采用BitMap格式进行可视化,高程越高,越接近白色
2、计算坡度值,并采用分层设色法可视化
3、河流提取
(1)首先进行填洼操作,本程序中采用了Moran和Vezina算法,首先用一极大高程水面将原始DEM数据表面淹没,然后通过迭代
去除 DEM上多余的水,最后得到的高程就是填洼后的高程。
(2)水流方向提取采用了D8算法
(3)汇水量计算,主要涉及到一个递归算法。

1、数据读取与可视化

//文件菜单中打开文件private void 打开OToolStripMenuItem_Click(object sender, EventArgs e){this.openFileDialog1.ShowDialog();if (this.openFileDialog1.FileName != ""){this.filename = this.openFileDialog1.FileName;}}//获取原始数据,并将DEM矩阵转换成位图BITMAP输出public void 原始数据绘图ToolStripMenuItem_Click(object sender, EventArgs e){//读取文件StreamReader streamReadfile = new StreamReader(this.filename);string data = streamReadfile.ReadToEnd();string[] strLine = data.Split('\n');//换行符分割字符串  NRows = Int32.Parse(this.textBox1.Text);NCols = Int32.Parse(this.textBox2.Text);//读取DEM数据,将高程值保存在二维数组中DEM = new double[NRows, NCols];string[] str1;int rgb;//寄存灰度int i; int j;int MaxBit = 2000;//最大高程值int MinBit = 0;   //最小高程值Bitmap Primary = new Bitmap(NRows, NCols, PixelFormat.Format32bppRgb);//文本数据转换成二维double数据{for (i = 0; i < NRows; i++){str1 = strLine[i].Split(',');for (j = 0; j < NCols; j++){DEM[i, j] = Convert.ToDouble(str1[j]);}}}//转换成BMP,高程值越大,颜色越趋向于白色{for (i = 0; i < NRows; i++){for (j = 0; j < NCols; j++){rgb = Convert.ToInt32(255 * (DEM[i, j] - MinBit) / (MaxBit - MinBit));Color pixelColor = Color.FromArgb(rgb, rgb, rgb);Primary.SetPixel(i, j, pixelColor);}}}//输出位图{Graphics g = this.CreateGraphics();g.DrawImage(Primary, 50, 60);g.Dispose();}}

2、坡度的计算

 //计算坡度,并用分层设色法输出private void 坡度toolStripMenuItem_Click(object sender, EventArgs e){int cellsize = Int32.Parse(this.textBox3.Text); //获取数据分辨率double[,] Slope = new double[NRows, NCols];    //坡度矩阵double fx, fy; //x方向和y方向int i, j;//计算坡度{for (i = 1; i < NRows - 1; i++){for (j = 1; j < NCols - 1; j++){fx = (DEM[i - 1, j + 1] - DEM[i - 1, j - 1] + 2 * (DEM[i, j + 1] - DEM[i, j - 1]) + DEM[i + 1, j + 1] - DEM[i + 1, j - 1]) / (8 * cellsize);fy = (DEM[i + 1, j - 1] - DEM[i - 1, j - 1] + 2 * (DEM[i + 1, j] - DEM[i - 1, j]) + DEM[i + 1, j + 1] - DEM[i - 1, j + 1]) / (8 * cellsize);Slope[i, j] = Math.Atan(Math.Sqrt(fx * fx + fy * fy)) * 57.29578;//转换成角度制}}}Bitmap slope = new Bitmap(NRows - 2, NCols - 2, PixelFormat.Format32bppRgb); //slope为坡度位图//转换成BMP,用不同的颜色表示不同的坡度int red; int green; int blue;//RGB色彩表示法{for (i = 1; i < NRows - 1; i++){for (j = 1; j < NCols - 1; j++){if (Slope[i, j] < 2){ red = 56; green = 168; blue = 0; }else if (Slope[i, j] < 4){ red = 139; green = 209; blue = 0; }else if (Slope[i, j] < 6){ red = 255; green = 255; blue = 0; }else if (Slope[i, j] < 8){ red = 255; green = 180; blue = 0; }else if (Slope[i, j] < 10){ red = 255; green = 90; blue = 0; }else{ red = 255; green = 0; blue = 0; }Color pixelColor = Color.FromArgb(red, green, blue);slope.SetPixel(i - 1, j - 1, pixelColor);}}}//输出坡度图{Graphics g = this.CreateGraphics();g.DrawImage(slope, 650, 60);g.Dispose();}}

3、河流提取

        private void 河流提取toolStripMenuItem_Click(object sender,EventArgs e){int[,] river = Water(D8(Fill(DEM)));Bitmap River = new Bitmap(NRows, NCols, PixelFormat.Format32bppRgb);int Limit = Convert.ToInt32(this.toolStripComboBox1.Text);for (int i = 0; i < NRows; i++){for (int j = 0; j < NCols; j++){if (river[i, j] > Limit){Color pixelColor = Color.FromArgb(255, 255, 255);River.SetPixel(i, j, pixelColor);}}}//输出位图{Graphics g = this.CreateGraphics();g.DrawImage(River, 300, 200);g.Dispose();}}//填充洼地算法,采用的是Moran和Vezina算法public double[,] Fill(double[,]DEM){int H = 2000;//设置水面高度double[,] Fill = new double[NRows, NCols];//初始化for (int i = 0; i < NRows; i++){for (int j = 0; j < NCols; j++){if (i == 0 || i == NRows - 1 || j == 0 || j == NCols - 1){Fill[i, j] = DEM[i, j];}else{Fill[i, j] = H;}}}bool Y_N;//采用迭代思想,去除多余的水do{Y_N = false;for (int i = 0; i < NRows; i++){for (int j = 0; j < NCols; j++){if (Fill[i, j] > DEM[i, j]){for (int N = -1; N <= 1; N++){for (int M = -1; M <= 1; M++){if ((N != 0) || (M != 0)){if (Fill[i, j] > Fill[i + N, j + M] + 0.00000001){Fill[i, j] = Fill[i + N, j + M] + 0.00000001;Y_N = true;}if (DEM[i, j] >= Fill[i + N, j + M] + 0.00000001){Fill[i, j] = DEM[i, j];}}}}}}}} while (Y_N == true);return Fill;}//D8算法public int[,] D8(double[,] Fill){/*流向矩阵表示如下:6  7  85  K  14  3  2    *///Fill[,] 是经过无洼地处理后的带有高程值的矩阵,  Direction[,]是流向矩阵(用于最后输出)int[,] Direction = new int[NRows, NCols];  //水流方向矩阵//Direction、Water初始化为0for (int i = 0; i < NRows; i++)//初始化为0{for (int j = 0; j < NCols; j++){Direction[i, j] = 0;}}//解求Direction矩阵double L = Convert.ToDouble(this.textBox3.Text);for (int i = 1; i < NRows - 1; i++){for (int j = 1; j < NCols - 1; j++){double[] direction = new double[8];    //寄存高差                                             // 用高程差在List中的顺序表示数字指代的方向direction[0] = (Fill[i, j] - Fill[i, j + 1]) / L; direction[1] = (Fill[i, j] - Fill[i + 1, j + 1]) / (L * Math.Sqrt(2)); //1、2方向direction[2] = (Fill[i, j] - Fill[i + 1, j]) / L; direction[3] = (Fill[i, j] - Fill[i + 1, j - 1]) / (L * Math.Sqrt(2));//3、4方向direction[4] = (Fill[i, j] - Fill[i, j - 1]) / L; direction[5] = (Fill[i, j] - Fill[i - 1, j - 1]) / (L * Math.Sqrt(2)); //5、6方向direction[6] = (Fill[i, j] - Fill[i - 1, j]) / L; direction[7] = (Fill[i, j] - Fill[i - 1, j + 1]) / (L * Math.Sqrt(2));//7、8方向double max = direction[0];int NUM = 0;for (int n = 7; n >= 0; n--){if (direction[n] >= max){max = direction[n];NUM = n + 1;}}Direction[i, j] = NUM;}}return Direction;}//水量汇聚算法public int[,] Water(int[,] Direction){int[,] WATER = new int[NRows, NCols];for (int i = 0; i < NRows; i++){for (int j = 0; j < NCols; j++){WATER[i, j] = 0;}}for (int i = 1; i < NRows - 1; i++){for (int j = 1; j < NCols - 1; j++){WATER[i, j] = Cal(i, j, Direction, WATER);}}int Cal(int i, int j, int[,] dir, int[,] water){if (water[i, j] == 0){water[i, j] = 1;//中间点的情况,8方向if ((i < NRows - 1) && (i > 0) && (j < NCols - 1) && (j > 0)){if (dir[i, j + 1] == 5){ water[i, j] += Cal(i, j + 1, dir, water); }if (dir[i + 1, j + 1] == 6){ water[i, j] += Cal(i + 1, j + 1, dir, water); }if (dir[i + 1, j - 1] == 8){ water[i, j] += Cal(i + 1, j - 1, dir, water); }if (dir[i, j - 1] == 1){ water[i, j] += Cal(i, j - 1, dir, water); }if (dir[i - 1, j - 1] == 2){ water[i, j] += Cal(i - 1, j - 1, dir, water); }if (dir[i - 1, j] == 3){ water[i, j] += Cal(i - 1, j, dir, water); }if (dir[i - 1, j + 1] == 4){ water[i, j] += Cal(i - 1, j + 1, dir, water); }if (dir[i + 1, j] == 7){ water[i, j] += Cal(i + 1, j, dir, water); }}}return water[i, j];}return WATER;}

完整代码:
https://download.csdn.net/download/qq_45767140/20323976

欢迎大家批评指正。

基于DEM数据的河流提取相关推荐

  1. matlab读取电子海图,基于dem数据叠加的航海雷达回波模拟方法

    基于dem数据叠加的航海雷达回波模拟方法 [技术领域] [0001] 本发明涉及航海雷达的回波模拟系统,具体是一种基于DEM(Digital Elevation Model,数字高程模型)数据叠加的航 ...

  2. 【QGIS入门实战精品教程】10.1:QGIS基于DEM数据的地形分析案例教程

    本文讲解QGIS中基于DEM数据的地形分析方法,包括:坡度分析.坡向分析.山体阴影.地貌分析.强度指数(地形复杂性). 文章目录 一.加载DEM 二.坡度分析 三.坡向分析 四.山体阴影 五.地貌分析 ...

  3. MIKE 21 教程 1.6 基于DEM数据设置河道高程

    目录 1 提取需要范围的DEM数据 2 重采样 3 栅格转点 4 文件导入 上一篇文章讲解了如何在GIS中基于卫星描绘河道边界 MIKE 21 教程 1.5 基于卫星影像绘制河道边界 本节讲解如何使用 ...

  4. ArcGIS基于DEM提取微流域单元(附练习数据下载)

    流域作为一个相对独立的地理单元,与行政区的划分有着本质上的区别.流域的划分更注重自然因素,流域作为一个综合的自然整体,在其内部形成了一个天然的物质与能量流动的场所,并通过水流的作用,与周围的区域进行物 ...

  5. ArcMap 基于DEM的基础地形分析

    1.高程分析 高程是我们对设计基地最基础的地形认知之一了.如前文所述,DEM的中文名叫"数字高程模型",也就是把我们生活周边的地形通过计算机进行数字模拟后的数据,大到我们整个地球乃 ...

  6. 基于无人机倾斜摄影模型提取高精度地形DEM数据

    1背景介绍 很多没有激光雷达设备的用户,也想生成地形数据,这时我们可以想到目前各个行业都普遍在使用的设备-无人机. 伴随着无人机倾斜摄影技术的普及和发展,不仅让我们能够快速获取城市三维模型,还能提供高 ...

  7. 基于DEM的GIS水文分析——河网与集水区域的提取

    基于DEM的GIS水文分析*--河网与集水区域的提取* DEM(Digital Elevation Model),是地表形态高程属性的数字化表达,能够一定分辨率的局部地形特征,包含了丰富的地形地貌.水 ...

  8. arcgis dem栅格立体感_如何使用ArcGIS从DEM数据中提取水系

    1. 概述 在比较偏远的地方,往往会缺少水文信息,我们可以通过ArcGIS对高程DEM数据进行水文分析,为地表水流建立模型,进而获取到该地的水文信息,DEM数据精度越高,获取到的水文数据精度也就越高, ...

  9. arcmap提取dem高程_如何使用ArcGIS从DEM数据中提取水系

    1. 概述 在比较偏远的地方,往往会缺少水文信息,我们可以通过ArcGIS对高程DEM数据进行水文分析,为地表水流建立模型,进而获取到该地的水文信息,DEM数据精度越高,获取到的水文数据精度也就越高, ...

  10. python实现dem输出三维模型_资源三号卫星影像立体像对如何提取DEM数据的方法

    原标题:资源三号卫星影像立体像对如何提取DEM数据的方法 OrthoMapping是ArcGIS 10.5推出的基于无人机.大飞机.卫星拍摄的原始影像获取专业级别信息产品的生产能力.使用OrthoMa ...

最新文章

  1. Java 8 - 05 方法引用
  2. php连接mysql总结_php连接数据库的三种方式的总结
  3. android震动提示音,android的消息提示(震动与提示音)
  4. Luogu P2735 电网【真·计算几何/Pick定理】By cellur925
  5. Spring 基于Java的Bean声明
  6. Circle and Points POJ - 1981(单位圆覆盖最多点)
  7. 可应用于实际的14个NLP突破性研究成果(四)
  8. this.getstate_Java线程类Thread.State getState()方法(带示例)
  9. 音乐学院计算机考试内容,中国音乐学院2014年秋季本科考试试卷-计算机基础C
  10. LINUX UBUNTU安装依赖库编译freeswitch
  11. 最经典的人生定律、法则、效应总结
  12. 【五校联考2015 8.20】宝藏
  13. 【一周读书】All life is problem solving
  14. OSChina 周日乱弹 —— 你撞鬼了吗?
  15. 如何快速提高视唱练耳能力
  16. java项目---探花交友
  17. Handler 简介
  18. 环洋市场调研-2021年全球颜料红2行业调研及趋势分析报告
  19. 【C#本质论 二】数据类型
  20. 12864点阵型液晶显示屏的工作原理

热门文章

  1. Java实现生成二维码(含logo)
  2. 硬件设计规范化 - 原理图和 PCB 的版本号命名规则
  3. 纪念 C语言之父 丹尼斯·里奇 逝世11周年:他发明了计算机世界的钢筋水泥!...
  4. 计算机网络课设--小型企业网络的规划与设计
  5. QT5.9 for 安卓开发 环境配置
  6. java情话代码,程序员浪漫的二进制表白代码
  7. 云计算 third day
  8. Practical JXTA II
  9. Stm32是用C语言编程吗,stm32编程软件是什么 stm32用什么软件编程
  10. 软件验收工作流程及准则