有源淹没分析arcgis_洪涝有源淹没算法及淹没结果分析
洪涝模拟仿真的实现方法主要有两种:一种是基于水动力学的洪水演进模型;还有一种是基于DEM的洪水淹没分析。详细分析例如以下:
我是GIS从业者,从我们的专业角度出发,选择基于DEM的洪水淹没分析来做洪涝的模拟仿真。而基于DEM的洪水淹没分析方法主要分为有源淹没和无源淹没。
本篇博客採用有源淹没算法实现洪涝的模拟,算法为八领域种子扩散算法。
採用C#版本号GDAL编写了FloodSimulation类,以下给出所有源码:
class FloodSimulation
{
#region 类成员变量
//点结构体
public struct Point
{
public int X; //行号
public int Y; //列号
public int Elevation; //像素值(高程值)
public bool IsFlooded; //淹没标记
};
private bool[,] IsFlood; //淹没区域标记二维数组,用于标记淹没栅格
private List m_FloodBufferList; //淹没缓冲区堆栈
public Dataset m_DEMDataSet; //DEM数据集
public Dataset m_FloodSimulatedDataSet; //洪涝淹没范围数据集
public int m_XSize; //数据X方向栅格个数
public int m_YSize; //数据Y方向栅格个数
public OSGeo.GDAL.Driver driver; //影像格式驱动
public int[] m_FloodBuffer; //填充缓冲区(洪涝淹没范围)
public int[] m_DEMdataBuffer; //DEM数据(存储高程值)
public double m_AreaFlooded; //水面面积
public double m_WaterVolume; //淹没水体体积
/* 这里的GeoTransform(影像坐标变换參数)的定义是:通过像素所在的行列值得到其左上角点空间坐标的运算參数
比如:某图像上(P,L)点左上角的实际空间坐标为:
Xp = GeoTransform[0] + P * GeoTransform[1] + L * GeoTransform[2];
Yp = GeoTransform[3] + P * GeoTransform[4] + L * GeoTransform[5]; */
public double[] m_adfGeoTransform;
#endregion
//构造函数
public FloodSimulation()
{
m_adfGeoTransform = new double[6];
m_FloodBufferList = new List();
}
///
/// 载入淹没区DEM,并创建淹没范围影像
///
/// DEM文件路径
///
public void loadDataSet(string m_DEMFilePath)
{
//读取DEM数据
m_DEMDataSet = Gdal.Open(m_DEMFilePath, Access.GA_ReadOnly);
m_XSize = m_DEMDataSet.RasterXSize;
m_YSize = m_DEMDataSet.RasterYSize;
//获取影像坐标转换參数
m_DEMDataSet.GetGeoTransform(m_adfGeoTransform);
//读取DEM数据到内存中
Band m_DEMBand = m_DEMDataSet.GetRasterBand(1); //获取第一个波段
m_DEMdataBuffer = new int [m_XSize * m_YSize];
m_DEMBand.ReadRaster(0, 0, m_XSize, m_YSize, m_DEMdataBuffer, m_XSize, m_YSize, 0, 0);
//淹没范围填充缓冲区
m_FloodBuffer = new int[m_XSize * m_YSize];
IsFlood=new bool[m_XSize,m_YSize];
//初始化二维淹没区bool数组
for (int i = 0; i < m_XSize; i++)
{
for (int j = 0; j < m_YSize; j++)
{
IsFlood[i, j] = false;
}
}
//创建洪涝淹没范围影像
string m_FloodImagePath = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\FloodSimulation\\FloodedRegion.tif";
if (System.IO.File.Exists(m_FloodImagePath))
{
System.IO.File.Delete(m_FloodImagePath);
}
//在GDAL中创建影像,先须要明白待创建影像的格式,并获取到该影像格式的驱动
driver = Gdal.GetDriverByName("GTiff");
//调用Creat函数创建影像
// m_FloodSimulatedDataSet = driver.CreateCopy(m_FloodImagePath, m_DEMDataSet, 1, null, null, null);
m_FloodSimulatedDataSet = driver.Create(m_FloodImagePath, m_XSize, m_YSize, 1, DataType.GDT_Float32, null);
//设置影像属性
m_FloodSimulatedDataSet.SetGeoTransform(m_adfGeoTransform); //影像转换參数
m_FloodSimulatedDataSet.SetProjection(m_DEMDataSet.GetProjectionRef()); //投影
//m_FloodSimulatedDataSet.WriteRaster(0, 0, m_XSize, m_YSize, m_FloodBuffer, m_XSize, m_YSize, 1, null, 0, 0, 0);
//输出影像
m_FloodSimulatedDataSet.GetRasterBand(1).WriteRaster(0, 0, m_XSize, m_YSize, m_FloodBuffer, m_XSize, m_YSize, 0, 0);
m_FloodSimulatedDataSet.GetRasterBand(1).FlushCache();
m_FloodSimulatedDataSet.FlushCache();
}
///
/// 种子扩散算法淹没分析
///
/// 种子点纬度
/// 种子点经度
/// 淹没水位
public void FloodFill8Direct(double m_Lat,double m_Log,double m_FloodLevel)
{
//首先依据种子点经纬度获取其所在行列号
Point pFloodSourcePoint = new Point();
int x, y;
geoToImageSpace(m_adfGeoTransform, m_Log, m_Lat, out x, out y);
pFloodSourcePoint.X = x;
pFloodSourcePoint.Y = y;
//获取种子点高程值
pFloodSourcePoint.Elevation = GetElevation(pFloodSourcePoint);
m_FloodBufferList.Add(pFloodSourcePoint);
//推断堆栈中时候还有未被淹没点,如有继续搜索。没有则淹没分析结束。
while (m_FloodBufferList.Count!=0)
{
Point pFloodSourcePoint_temp = m_FloodBufferList[0];
int rowX = pFloodSourcePoint_temp.X;
int colmY = pFloodSourcePoint_temp.Y;
//标记可淹没,并从淹没堆栈中移出
IsFlood[rowX, colmY] = true;
m_FloodBuffer[getIndex(pFloodSourcePoint_temp)] = 1;
m_FloodBufferList.RemoveAt(0);
//向中心栅格单元的8个临近方向搜索连通域
for (int i = rowX - 1; i < rowX + 2; i++)
{
for (int j = colmY - 1; j < colmY + 2; j++)
{
//推断是否到达栅格边界
if (i<=m_XSize&&j<=m_YSize)
{
Point temp_point = new Point();
temp_point.X = i;
temp_point.Y = j;
temp_point.Elevation = GetElevation(temp_point);
//搜索能够淹没且未被标记的栅格单元
if ((temp_point.Elevation
{
//将符合条件的栅格单元增加堆栈,标记为淹没,避免反复运算
m_FloodBufferList.Add(temp_point);
IsFlood[temp_point.X, temp_point.Y] = true;
m_FloodBuffer[getIndex(temp_point)] = 1;
}
}
}
}
}
//统计淹没网格数
int count = 0;
for (int i = 0; i < m_XSize; i++)
{
for (int j = 0; j < m_YSize; j++)
{
if (IsFlood[i,j]==true)
{
count++;
}
}
}
}
///
/// 输出洪涝淹没范围图
///
public void OutPutFloodRegion()
{
m_FloodSimulatedDataSet.GetRasterBand(1).WriteRaster(0, 0, m_XSize, m_YSize, m_FloodBuffer, m_XSize, m_YSize, 0, 0);
// m_FloodSimulatedDataSet.WriteRaster(0, 0, m_XSize, m_YSize, m_FloodBuffer, m_XSize, m_YSize, 1, null, 0, 0, 0);
m_FloodSimulatedDataSet.GetRasterBand(1).FlushCache();
m_FloodSimulatedDataSet.FlushCache();
}
// public void OutPutFloodedInfo()
// {
// }
///
/// 获取第x行第y列栅格索引
///
/// 栅格点
/// 该点在DEM内存数组中的索引
private int getIndex(Point point)
{
return point.Y* m_XSize + point.X;
}
///
/// 获取高程值
///
/// 栅格点
/// 高程值
private int GetElevation(Point m_point)
{
return m_DEMdataBuffer[getIndex(m_point)];
}
///
/// 从像素空间转换到地理空间
///
/// 影像坐标变换參数
/// 像素所在行
/// 像素所在列
/// X
/// Y
public void imageToGeoSpace(double[] m_GeoTransform, int pixel, int line, out double X, out double Y)
{
X = m_GeoTransform[0] + pixel * m_GeoTransform[1] + line * m_GeoTransform[2];
Y = m_GeoTransform[3] + pixel * m_GeoTransform[4] + line * m_GeoTransform[5];
}
///
/// 从地理空间转换到像素空间
///
/// 影像坐标变化參数
/// X(经度)
/// Y(纬度)
/// 像素所在行
/// 像素所在列
public void geoToImageSpace(double[] m_GeoTransform, double x, double y, out int pixel, out int line)
{
line = (int)((y * m_GeoTransform[1] - x * m_GeoTransform[4] + m_GeoTransform[0] * m_GeoTransform[4] - m_GeoTransform[3] * m_GeoTransform[1]) / (m_GeoTransform[5] * m_GeoTransform[1] - m_GeoTransform[2] * m_GeoTransform[4]));
pixel = (int)((x - m_GeoTransform[0] - line * m_GeoTransform[2]) / m_GeoTransform[1]);
}
}
模拟结果在ArcGlobe中的显示效果图:
欢迎大家留言交流。
有源淹没分析arcgis_洪涝有源淹没算法及淹没结果分析相关推荐
- 大数据挖掘建模案例分析:利用BP神经网络算法进行用户行为分析(一)
泰迪智能科技(数据挖掘平台:TipDM数据挖掘平台)最新推出的数据挖掘实战专栏 专栏将数据挖掘理论与项目案例实践相结合,可以让大家获得真实的数据挖掘学习与实践环境,更快.更好的学习数据挖掘知识与积累职 ...
- 有源电力滤波器matlab仿真, 并联型apf仿真fft分析 谐波电流检测ipiq法
有源电力滤波器matlab仿真, 并联型apf仿真fft分析 谐波电流检测ipiq法 跟踪电流控制(传统滞环控制 空间电压矢量滞环控制) 总谐波畸变率降至3%以下 ID:695064569089802 ...
- 图像处理中,SIFT,FAST,MSER,STAR等特征提取算法的比较与分析(利用openCV实现)
图像处理中,SIFT,FAST,MSER,STAR等特征提取算法的比较与分析(利用openCV实现) 本文实验为自己原创,转载请注明出处. 本人为研究生,最近的研究方向是物体识别.所以就将常用的几种特 ...
- 【模电】0008 有源滤波器3(二阶有源高通、带通、带阻滤波器)
上一节我们分析了二阶有源低通滤波器,这一节我们来继续,分析其他种类的二阶滤波器,包括高通.带通.带阻滤波器. 由于分析过程是类似的,都是以节点列方程,化简后得到传递函数,本篇就不具体写计算过程了,直接 ...
- SURF算法与源码分析、下
FROM: http://www.cnblogs.com/ronny/p/4048213.html 上一篇文章 SURF算法与源码分析.上 中主要分析的是SURF特征点定位的算法原理与相关OpenCV ...
- 【Android 内存优化】Java 内存模型 ( Java 虚拟机内存模型 | 线程私有区 | 共享数据区 | 内存回收算法 | 引用计数 | 可达性分析 )
文章目录 一. Java 虚拟机内存模型 二. 程序计数器 ( 线程私有区 ) 三. 虚拟机栈 ( 线程私有区 ) 四. 本地方法栈 ( 线程私有区 ) 五. 方法区 ( 共享数据区 ) 1. 方法区 ...
- 算法导论之平摊分析(动态表)
平摊分析,amortizedanalysis,对数据结构执行的所有操作的总和时间是油由求平均而得出,用来证明一系列操作中,通过对所有操作求平均代价,即时某一操作具有较大代价,但平均代价还是小的.导论中 ...
- ML/DL之预测分析类:利用机器学习算法进行预测分析的简介、分析、代码实现之详细攻略
ML/DL之预测分析类:利用机器学习算法进行预测分析的简介.分析.代码实现之详细攻略 目录 机器学习算法进行预测的简介 机器学习算法进行预测的分析 机器学习算法进行预测的代码实现 机器学习算法进行预测 ...
- 动图图解C语言插入排序算法,含代码分析
C语言文章更新目录 C语言学习资源汇总,史上最全面总结,没有之一 C/C++学习资源(百度云盘链接) 计算机二级资料(过级专用) C语言学习路线(从入门到实战) 编写C语言程序的7个步骤和编程机制 C ...
最新文章
- 如何删除linux的root权限,永久删除现代Linux的root权限
- Windows下程序打包发布时的小技巧
- C/C++:程序的内存分配方式
- 前端学习(1485):restful接口规则
- php excel 设置常规_php实现的操作excel类详解
- php 写入sql server,php将图片直接写入SQLServer2008
- Scrapy爬虫笔记
- POJ3737 UmBasketella
- JS中的==和===的区别
- PYSQLITE用法初探
- (转)深度学习是经验主义新高峰,不是理性主义终结
- LeetCode 144. Binary Tree Preorder Traversal 20170706
- UE4_BIM替换材质处理流程
- 根据输入的银行卡号识别出银行名称并显示
- c语言酒店管理系统,基于C#的酒店管理系统(V3.1)最新版
- ONF与天地互连共同成立开放SDN推广中心(OSPC)
- 【python】基础网络爬虫教程
- 単語境界/非単語境界(¥b, ¥B)
- ARM SMMU介绍
- .NET开发十大常用工具软件分享