/// <summary> /// 计算平均坡度和坡长 /// </summary> /// <param name="point"></param> /// <param name="reader"></param> /// <param name="avglength"></param> /// <param name="avgslope"></param> public void CalAvgSlopeLength(List <Point3d> points, RasterReader reader, ref double avglength, ref double avgslope) { double totalLength = 0; double totalSlope = 0; if (points != null && points.Count > 0) { int count = 0; for (int i = 0; i < points.Count; i++) { Point3d startpt = points[i]; List <Point3d> resultPt = GetMaxSlopePoints(points[i], reader); double singleLength = 0; double singleSlope = 0; for (int j = 0; j < resultPt.Count; j++) { Point3d point1 = resultPt[i]; Point3d point2 = resultPt[resultPt.Count - 1]; singleLength += RasterCoefficientReader.Length(point1, point2); } singleSlope = Math.Abs((startpt.Z - resultPt[resultPt.Count - 1].Z) / (RasterCoefficientReader.Length(startpt, resultPt[resultPt.Count - 1]))); totalSlope += singleSlope; totalLength += singleLength; count = points.Count * resultPt.Count; FormOutput.AppendProress(((i + 1) * 100) / points.Count); } avglength = totalLength / (1000 * count); avgslope = totalSlope * 1000 / points.Count; } }
private void WatershedArea(string shppath, string rasterpath, ref double _resultProjectArea, ref double?_resultSurfaceArea) { //获取流域面积形状以及它的外接矩形 GeoRect _analysisRect = new GeoRect(-90, 90, 180, -180); //外接矩形 iTelluroLib.GeoTools.Geometries.Polygon _analysisPolygon = _hydrology.CalLimitAreaPolygon(shppath, ref _analysisRect); //流域面形状 //在存在流域面积界定的情况下要进行裁剪筛选,不存在默认全部计算 RasterReader raster = new RasterReader(rasterpath); double _widthStep = raster.CellSizeX; double _heightStep = raster.CellSizeY; // 网格大小:行、列数 int _widthNum = (int)((_analysisRect.East - _analysisRect.West) / _widthStep); int _heightNum = (int)((_analysisRect.North - _analysisRect.South) / _heightStep); _terrainTile = new TerrainPoint[_widthNum, _heightNum]; //构建高程矩阵 for (int i = 0; i < _widthNum; i++) { for (int j = 0; j < _heightNum; j++) { TerrainPoint tp = new TerrainPoint(); tp.Longitude = _analysisRect.West + i * _widthStep; tp.Latitude = _analysisRect.South + j * _heightStep; tp.Altitude = ReadBand(raster, i, j); tp.col = i; tp.row = j; _terrainTile[i, j] = tp; } } double _cellArea = CaculateCellAera(raster, _widthNum, _heightNum); //坡度计算 if (_resultSurfaceArea == null) { _resultSurfaceArea = 0; } for (int i = 0; i < _widthNum; i++) { for (int j = 0; j < _heightNum; j++) { TerrainPoint tp = _terrainTile[i, j]; iTelluroLib.GeoTools.Geometries.Point currentPoint = new iTelluroLib.GeoTools.Geometries.Point(tp.Longitude, tp.Latitude); if ((_analysisPolygon != null && _analysisPolygon.Contains(currentPoint)) || _analysisPolygon == null) { _resultProjectArea += _cellArea; //计算坡度 double slope = GetSlope(raster, tp); double currentCellArea = _cellArea / Math.Cos(slope); _resultSurfaceArea += currentCellArea; } } FormOutput.AppendProress(((i + 1) * 100) / _widthNum); } }
private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Result != null) { FormOutput.AppendLog(string.Format("提取结束,共耗时{0}秒..", (DateTime.Now - _currentTime).TotalSeconds)); System.Diagnostics.Process.Start("Explorer.exe", Path.GetDirectoryName(e.Result.ToString())); } FormOutput.AppendProress(false); currentDem = fileChooseControl1.FilePath; }
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { double[] result = e.Result as double[]; if (Convert.ToDouble(result[0]) != 0) { textBox1.Text = result[0].ToString(); } if (Convert.ToDouble(result[1]) != 0) { textBox2.Text = result[1].ToString(); } if (Convert.ToDouble(result[2]) != 0) { textBox3.Text = result[2].ToString(); } FormOutput.AppendProress(false); }
private double CaculateRiver(List <Dictionary <Point2d, Geometry> > dic, string tifPath, ref Dictionary <Point2d, Geometry> mainRiver) { RasterReader reader = new RasterReader(tifPath); //Dictionary<Point2d, Geometry> maxGeoLength = null; double maxLength = 0; //主沟道长度 List <Point3d> gradientPoints = new List <Point3d>(); // List<Point3d> gradientPoints1 = new List<Point3d>(); int percent = 0; foreach (var geoLength in dic) { double tempLength = 0; List <Point2d> pointListLength = new List <Point2d>(); gradientPoints = new List <Point3d>(); foreach (var length in geoLength) { int pcount = length.Value.GetPointCount(); for (int i = 0; i < pcount; i++) { Point2d temp = new Point2d(length.Value.GetX(i), length.Value.GetY(i)); if (!pointListLength.Contains(temp)) { pointListLength.Add(temp); gradientPoints.Add(new Point3d(length.Value.GetX(i), length.Value.GetY(i), GetElevationByPointInDEM(temp, reader))); } } } for (int i = 1; i < gradientPoints.Count; i++) { tempLength += GetLength(gradientPoints[i - 1], gradientPoints[i]); } if (maxLength < tempLength) { maxLength = tempLength; mainRiver = geoLength; //gradientPoints1 = gradientPoints; } percent++; FormOutput.AppendProress(percent * 50 / dic.Count); } reader.Dispose(); return(maxLength); }
/// <summary> /// 计算 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { if (!backgroundWorker1.IsBusy) { FormOutput.AppendLog("开始计算..."); FormOutput.AppendProress(true); _currentTime = DateTime.Now; SaveCaculateArg(); //获取计算参数 string tifPath = fileChooseControl1.FilePath; //影像路径 string areaShp = fileChooseControl2.FilePath; //流域面积shp string RShp = fileChooseControl3.FilePath; //系数R string rShp = fileChooseControl4.FilePath; //指数r //progressBar1.Visible = true; backgroundWorker1.RunWorkerAsync(new string[] { tifPath, areaShp, RShp, rShp }); } else { FormOutput.AppendLog("当前后台正在计算..."); } }
/// <summary> /// 开始计算 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { if (!backgroundWorker1.IsBusy) { FormOutput.AppendLog("开始计算..."); FormOutput.AppendProress(true); //保存计算参数 List <NodeModel> result = new List <NodeModel>(); NodeModel model = fileChooseControl1.SelectedValue; if (model != null) { CopyAddNodeModel(result, model); } NodeModel model1 = fileChooseControl2.SelectedValue; if (model1 != null) { CopyAddNodeModel(result, model1); } NodeModel model2 = fileChooseControl3.SelectedValue; if (model2 != null) { CopyAddNodeModel(result, model2); } _parent.OporateCaculateNode(Guids.PMHL, result.ToArray()); //获取计算参数 string tifPath = fileChooseControl1.FilePath; //影像路径 string mainShp = fileChooseControl3.FilePath; //主沟道shp string argShp = fileChooseControl2.FilePath; //流速系数 //progressBar1.Visible = true; backgroundWorker1.RunWorkerAsync(new string[] { mainShp, tifPath, argShp }); } else { FormOutput.AppendLog("当前后台正在计算..."); } }
private double GetLonGradient(Dictionary <Point2d, Geometry> mainRiver, string tifPath) { RasterReader reader = new RasterReader(tifPath); List <Point2d> pointList = new List <Point2d>(); List <Point3d> gradientPoints = new List <Point3d>(); int percent = 0; foreach (var item in mainRiver) { for (int i = 0; i < item.Value.GetPointCount(); i++) { Point2d temp = new Point2d(item.Value.GetX(i), item.Value.GetY(i)); if (!pointList.Contains(temp)) { pointList.Add(temp); gradientPoints.Add(new Point3d(item.Value.GetX(i), item.Value.GetY(i), GetElevationByPointInDEM(temp, reader))); } } percent++; FormOutput.AppendProress(50 + (percent * 50 / mainRiver.Count)); } double length = 0; double z = 0; double minElevation = gradientPoints[0].Z; for (int i = 1; i < gradientPoints.Count; i++) { if (minElevation > gradientPoints[i].Z) { minElevation = gradientPoints[i].Z; } Point3d point1 = gradientPoints[i - 1]; Point3d point2 = gradientPoints[i]; length += Length(point1, point2); z += Length(point1, point2) * (point1.Z + point2.Z); } return(z * 1000 / (length * length)); }
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //F,N,R,r double?[] result = e.Result as double?[]; if (result != null && result.Length >= 4) { if (result[0].HasValue) { textBox1.Text = result[0].GetValueOrDefault(0).ToString("f3"); textBox2.Text = result[1].GetValueOrDefault(0).ToString("f3"); } if (result[2].HasValue) { textBox3.Text = result[2].GetValueOrDefault(0).ToString("f3"); } if (result[3].HasValue) { txtr1.Text = result[3].GetValueOrDefault(0).ToString("f3"); } } FormOutput.AppendLog(string.Format("计算结束,共耗时{0}秒..", (DateTime.Now - _currentTime).TotalSeconds)); FormOutput.AppendProress(false); }
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { double[] result = e.Result as double[]; if (Convert.ToDouble(result[0]) != 0) { textBox1.Text = result[0].ToString(); } if (Convert.ToDouble(result[1]) != 0) { textBox2.Text = result[1].ToString(); } if (Convert.ToDouble(result[2]) != 0) { textBox3.Text = result[2].ToString(); } FormOutput.AppendProress(false); //输出主沟道到临时目录并且加载到三维球和节点 string tempPath = Path.Combine(Path.GetTempPath(), "主沟道" + DateTime.Now.ToString("HH_mm") + ".shp"); ShpReader shp = new ShpReader(fileChooseControl3.FilePath); CreateShp(tempPath, _mainRiver, shp.SpatialRef); _parent.AddShpLineLayerByPath(tempPath); }
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) { //读取高程矩阵 RasterReader read = new RasterReader(e.Argument as string); double[,] src = DEMReader.GetElevation(read); DEMReader.SaveDem(read, src, null, RiverPath); FormOutput.AppendLog("1.计算洼地"); List <MyGrid> SourceGrid = new List <MyGrid>(); MyGrid.Src = src; SourceGrid = MyGrid.GetSourceGrids(); FormOutput.AppendLog($"栅格点有{SourceGrid.Count},其中洼地点有{SourceGrid.Where(t => t.IsFill == false).Count()}"); FormOutput.AppendLog("2.开始填充洼地"); #region 指定填洼 int times = 1; while (SourceGrid.Where(t => t.IsFill == false).Count() > 0) { double[,] tempSrc = new double[src.GetLongLength(0), src.GetLongLength(1)]; foreach (var item in SourceGrid) { if (item.IsFill) { tempSrc[item.Row, item.Col] = item.ALT; } else { tempSrc[item.Row, item.Col] = item.FilledALT; } } MyGrid.Src = tempSrc; SourceGrid = MyGrid.GetSourceGrids(); FormOutput.AppendLog($"第{times}次填充洼地,栅格点有{SourceGrid.Count},其中洼地点有{SourceGrid.Where(t => t.IsFill == false).Count()}"); src = tempSrc; times++; } #endregion fillGrid = src; var ss = SourceGrid.OrderByDescending(t => t.ALT).ToList(); if (!string.IsNullOrEmpty(FillPath)) { DEMReader.SaveDem(read, fillGrid, null, FillPath); } FormOutput.AppendLog("填充洼地完成"); //计算流向 FormOutput.AppendLog("2.开始计算流向.."); FormOutput.AppendLog($"未确定流向的点有{SourceGrid.Where(t => t.IsFlat).Count()}"); directionDev = new int[src.GetLength(0), src.GetLength(1)]; int index = 0; FormOutput.AppendProress(true); foreach (var item in SourceGrid) { directionDev[item.Row, item.Col] = item.Direction; index++; FormOutput.AppendProress(index * 100 / SourceGrid.Count); } if (!string.IsNullOrEmpty(DirectionPath)) { DEMReader.SaveDem(read, directionDev, null, DirectionPath); } FormOutput.AppendLog("流向计算完成.."); FormOutput.AppendLog("3.开始计算汇流量.."); Accumulation = new int[src.GetLength(0), src.GetLength(1)]; for (int i1 = 0; i1 < src.GetLength(0); i1++) { FormOutput.AppendProress(i1 * 100 / src.GetLength(0)); for (int j1 = 0; j1 < src.GetLength(1); j1++) { int i = i1; int j = j1; bool flag = true; List <Point> caledPoint = new List <Point>(); while (flag) { //计算之后不计算,防止死循环 if (caledPoint.Where(t => t.X == i && t.Y == j).Any()) { break; } int direction = directionDev[i, j]; caledPoint.Add(new Point(i, j)); switch (direction) { case 1: Accumulation[i, j + 1]++; j = j + 1; break; case 2: Accumulation[i = 1, j + 1]++; i = i + 1; j = j + 1; break; case 4: Accumulation[i + 1, j]++; i = i + 1; break; case 8: Accumulation[i + 1, j - 1]++; i = i + 1; j = j - 1; break; case 16: Accumulation[i, j - 1]++; j = j - 1; break; case 32: Accumulation[i - 1, j - 1]++; i = i - 1; j = j - 1; break; case 64: Accumulation[i - 1, j]++; i = i - 1; break; case 128: Accumulation[i - 1, j + 1]++; i = i - 1; j = j + 1; break; default: break; } flag = direction != 0 && i < src.GetLength(0) && j < src.GetLength(1); } } } if (!string.IsNullOrEmpty(AccumulationPath)) { DEMReader.SaveDem(read, Accumulation, null, AccumulationPath); } FormOutput.AppendLog("计算汇流量完成.."); FormOutput.AppendLog("4.开始根据回流阀值提取河网.."); FormOutput.AppendLog($"当前阀值为{RiverThreshold}.."); RiverGrid = new int[src.GetLength(0), src.GetLength(1)]; for (int i = 0; i < Accumulation.GetLength(0); i++) { for (int j = 0; j < Accumulation.GetLength(1); j++) { if (Accumulation[i, j] < RiverThreshold) { RiverGrid[i, j] = -1; } else { RiverGrid[i, j] = 1; } } } DEMReader.SaveDem(read, RiverGrid, null, RiverPath); FormOutput.AppendLog("河网提取完成.."); e.Result = RiverPath; }
/// <summary> /// 3.水流积聚计算 /// 可以看到,生成的水流积聚栅格已经可以看到所产生的河网了。 /// 现在所需要做的就是把这些河网栅格提取出来。可以把产生的河网的支流的象素值作为阀值来提取河网栅格。 /// </summary> /// <param name="src"></param> /// <returns></returns> public static double[,] Accumulation(this double[,] src) { int rowCount = src.GetLength(0); int colCount = src.GetLength(1); double[,] result = new double[rowCount, colCount]; //定义结果 Dictionary <Grid, List <Grid> > dicCaledAll = new Dictionary <Grid, List <Grid> >(); Queue <Grid> queueGrid = new Queue <Grid>(); Dictionary <Grid, int> unFindOutGrid = new Dictionary <Grid, int>(); for (int row = 0; row < rowCount; row++) { for (int col = 0; col < colCount; col++) { //将数据添加到方程组中 Grid tempGrid = new Grid(row, col); queueGrid.Enqueue(tempGrid); unFindOutGrid.Add(tempGrid, 0); //添加默认为零 dicCaledAll.Add(tempGrid, GetFlowAround(src, tempGrid)); } } Dictionary <Grid, int> findOutGrid = new Dictionary <Grid, int>(); FormCalView.SetAllSize(rowCount, colCount); FormOutput.AppendProress(true); //开始解方程 while (queueGrid.Count > 0) { FormOutput.AppendProress(findOutGrid.Count * 100 / dicCaledAll.Count); Grid tGrid = queueGrid.Dequeue(); List <Grid> lstGrid = dicCaledAll[tGrid]; //找到数据 if (lstGrid.Count == 0) { result[tGrid.i, tGrid.j] = unFindOutGrid[tGrid]; findOutGrid.Add(tGrid, unFindOutGrid[tGrid]); dicCaledAll.Remove(tGrid); //unFindOutGrid.Remove(tGrid); FormCalView.SetColor(tGrid.i, tGrid.j, unFindOutGrid[tGrid]); } else { List <Grid> lstTemp = new List <Grid>(); lstTemp.AddRange(dicCaledAll[tGrid]); //循环寻找当前找出的Grid for (int i = 0; i < lstGrid.Count; i++) { Grid temp = lstGrid[i]; if (ContainsGrid(findOutGrid, temp)) { Grid temp1 = FindGrid(unFindOutGrid, temp); Grid temp2 = FindGrid(findOutGrid, temp); unFindOutGrid[temp1] = unFindOutGrid[temp1] + findOutGrid[temp2] + 1; lstTemp.Remove(temp); } } if (lstTemp.Count == 0) { result[tGrid.i, tGrid.j] = unFindOutGrid[tGrid]; findOutGrid.Add(tGrid, unFindOutGrid[tGrid]); dicCaledAll.Remove(tGrid); // unFindOutGrid.Remove(tGrid); FormCalView.SetColor(tGrid.i, tGrid.j, unFindOutGrid[tGrid]); } else { dicCaledAll[tGrid] = lstTemp; queueGrid.Enqueue(tGrid); } } } return(result); }