/// <summary> /// /// </summary> /// <param name="basic"></param> /// <param name="rasterFolderPath"></param> /// <param name="fileName"></param> /// <param name="cityName"></param> private void Overlay(RasterOp basic, string rasterFolderPath, string fileName, string cityName) { RasterReader reader = new RasterReader(rasterFolderPath, fileName + ".tif"); RasterOp op = new RasterOp(reader); Overlay(basic, op, CityValues[cityName]); }
/// <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 double GetSlope(RasterReader reader, TerrainPoint tp) { double zx = 0, zy = 0, ex = 0; if (tp.col - 1 > 0 && tp.row - 1 > 0 && tp.row + 1 < _terrainTile.GetLength(1) && tp.col + 1 < _terrainTile.GetLength(0)) { iTelluro.GlobeEngine.DataSource.Geometry.Point3d d1 = null, d2 = null; if (reader.IsProjected) { d1 = new Point3d(_terrainTile[tp.col - 1, tp.row].Longitude, tp.Latitude, tp.Altitude); d2 = new Point3d(_terrainTile[tp.col + 1, tp.row].Longitude, tp.Latitude, tp.Altitude); } else { d1 = MathEngine.SphericalToCartesianD( Angle.FromDegrees(tp.Latitude), Angle.FromDegrees(_terrainTile[tp.col - 1, tp.row].Longitude), //lon - demSpan GlobeTools.CurrentWorld.EquatorialRadius + tp.Altitude ); d2 = MathEngine.SphericalToCartesianD( Angle.FromDegrees(tp.Latitude), Angle.FromDegrees(_terrainTile[tp.col + 1, tp.row].Longitude), //lon + demSpan), GlobeTools.CurrentWorld.EquatorialRadius + tp.Altitude ); } iTelluro.GlobeEngine.DataSource.Geometry.Point3d segment = d2 - d1; ex = segment.Length; //zx = (elv[1, 2] - elv[1, 0]) / ex; //zy = (elv[2, 1] - elv[0, 1]) / ex; zx = (_terrainTile[tp.col + 1, tp.row + 0].Altitude - _terrainTile[tp.col - 1, tp.row + 0].Altitude) / ex; zy = (_terrainTile[tp.col + 0, tp.row + 1].Altitude - _terrainTile[tp.col + 0, tp.row - 1].Altitude) / ex; } return(Math.Atan(Math.Sqrt(zx * zx + zy * zy))); }
/// <summary> /// 计算线的交点 /// 先获取每条线段的startpoint与endpoint,然后判断是否有重合 /// </summary> private List <Point3d> CalPoints(string path, RasterReader reader) { ShpReader shp = new ShpReader(path); OSGeo.OGR.Feature ofea; List <Point3d> linePoint = new List <Point3d>(); List <OSGeo.OGR.Geometry> featureList = new List <OSGeo.OGR.Geometry>(); while (((ofea = shp.layer.GetNextFeature()) != null)) { int count = ofea.GetGeometryRef().GetPointCount(); Point3d start = new Point3d(ofea.GetGeometryRef().GetX(0), ofea.GetGeometryRef().GetY(0), GetElevationByPointInDEM(new Point2d(ofea.GetGeometryRef().GetX(0), ofea.GetGeometryRef().GetY(0)), reader)); Point3d end = new Point3d(ofea.GetGeometryRef().GetX(count - 1), ofea.GetGeometryRef().GetY(count - 1), GetElevationByPointInDEM(new Point2d(ofea.GetGeometryRef().GetX(0), ofea.GetGeometryRef().GetY(0)), reader)); if (!linePoint.Contains(start)) { linePoint.Add(start); } if (!linePoint.Contains(end)) { linePoint.Add(end); } featureList.Add(ofea.GetGeometryRef()); } return(linePoint.OrderBy(t => t.Y).ToList()); }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { string[] args = e.Argument as string[]; double avgLength = 0; double avgSlope = 0; if (File.Exists(args[0]) && File.Exists(args[1])) { FormOutput.AppendLog("开始获取线的交点..."); RasterReader reader = new RasterReader(args[1]); List <Point3d> pts = CalPoints(args[0], reader); FormOutput.AppendLog("开始计算平均坡度和坡长..."); CalAvgSlopeLength(pts, reader, ref avgLength, ref avgSlope); reader.Dispose(); FormOutput.AppendLog("平均坡长:" + avgLength.ToString("f3")); FormOutput.AppendLog("平均坡度:" + avgSlope.ToString("f3")); } double?r = null; if (File.Exists(args[1]) && File.Exists(args[2])) { FormOutput.AppendLog("开始计算坡面流速系数..."); r = RasterCoefficientReader.ReadCoeficient(args[2], args[1]); if (r.HasValue) { FormOutput.AppendLog("结果--坡面流速系数为:" + r.Value.ToString()); } } e.Result = new double[] { avgLength, avgSlope, r.GetValueOrDefault(0) }; }
/// <summary> /// 计算影像数据单元格的投影面积 /// (区分了文件为投影坐标还是地理坐标) /// </summary> /// <param name="reader"></param> /// <param name="_widthNum"></param> /// <param name="_heightNum"></param> /// <returns></returns> private double CaculateCellAera(RasterReader reader, int _widthNum, int _heightNum) { try { int ti, tj; ti = _widthNum / 2; tj = _heightNum / 2; iTelluro.GlobeEngine.DataSource.Geometry.Point3d p00, p01, p10; if (reader.IsProjected) { p00 = new Point3d(_terrainTile[ti, tj].Longitude, _terrainTile[ti, tj].Latitude, _terrainTile[ti, tj].Altitude); p01 = new Point3d(_terrainTile[ti, tj + 1].Longitude, _terrainTile[ti, tj + 1].Latitude, _terrainTile[ti, tj + 1].Altitude); p10 = new Point3d(_terrainTile[ti + 1, tj].Longitude, _terrainTile[ti + 1, tj].Latitude, _terrainTile[ti + 1, tj].Altitude); } else { double r = _globeView.GlobeViewSetting.EquatorialRadius + _terrainTile[ti, tj].Altitude; p00 = MathEngine.SphericalToCartesianD(Angle.FromDegrees(_terrainTile[ti, tj].Latitude), Angle.FromDegrees(_terrainTile[ti, tj].Longitude), r); p01 = MathEngine.SphericalToCartesianD(Angle.FromDegrees(_terrainTile[ti, tj + 1].Latitude), Angle.FromDegrees(_terrainTile[ti, tj + 1].Longitude), r); p10 = MathEngine.SphericalToCartesianD(Angle.FromDegrees(_terrainTile[ti + 1, tj].Latitude), Angle.FromDegrees(_terrainTile[ti + 1, tj].Longitude), r); } double area = (p00 - p01).Length * (p00 - p10).Length; return(area); } catch (Exception ex) { FormOutput.AppendLog(ex.Message); return(0); } }
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 Run(RasterReader reader, CalculatorCity city, string folderPath) { RasterOp rasterOp = new RasterOp(reader); Postion pos = reader.Coordinate(city.XCoord, city.YCoord); var result = rasterOp.Calculator(pos); RasterWriter writer = new RasterWriter(folderPath, city.Name + "_高铁未通车", reader.RasterInfo); result.WriteRaster(writer, "TIFF"); }
private void Init() { var firstCity = Cities.First(item => item.IsSelected); RasterReader reader = new RasterReader(HighTrainNoFolderPath, firstCity.Name + "_高铁未通车" + ".tif"); Info = reader.RasterInfo; RasterOp = new RasterOp(reader); RasterOp.Reset(); }
private void Run(object p) { Hashtable para = p as Hashtable; ContinuousWait wait = para["wait"] as ContinuousWait; var folderPath = para["folderPath"].ToString(); try { string preWorkSpace = Path.GetDirectoryName(_preRasterFilePath); string preFileName = Path.GetFileNameWithoutExtension(_preRasterFilePath); string aftWorkSpace = Path.GetDirectoryName(_aftRasterFilePath); string aftFileName = Path.GetFileNameWithoutExtension(_aftRasterFilePath); RasterReader preReader = new RasterReader(preWorkSpace, preFileName + ".tif"); RasterReader aftReader = new RasterReader(aftWorkSpace, aftFileName + ".tif"); RasterOp preOp = new RasterOp(preReader); RasterOp aftOp = new RasterOp(aftReader); RasterOp res = preOp.Clone(); res.Reset(); for (int i = 0; i < preOp.Width; i++) { for (int j = 0; j < preOp.Height; j++) { if (preOp.Read(i, j).HasValue) { float orgin = (float)preOp.Read(i, j); float now = (float)aftOp.Read(i, j); if (Math.Abs(orgin) > 10e-5) { float rate = (now - orgin) / orgin; res.Write(i, j, rate); } } } } RasterWriter writer = new RasterWriter(folderPath, RasterName, preReader.RasterInfo); res.WriteRaster(writer, "TIFF"); para["ret"] = true; } catch (Exception e) { _log.Error(e.GetType() + e.Message + e.StackTrace); para["ret"] = false; } finally { wait.CloseWait(); } }
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); }
private double GetElevationByPointInDEM(Point2d sourcePoint, RasterReader raster) { try { double[] adfGeoTransform = new double[6]; raster.DataSet.GetGeoTransform(adfGeoTransform); double dTemp = adfGeoTransform[1] * adfGeoTransform[5] - adfGeoTransform[2] * adfGeoTransform[4]; double dRow = 0; double dCol = 0; dCol = (adfGeoTransform[5] * (sourcePoint.X - adfGeoTransform[0]) - adfGeoTransform[2] * (sourcePoint.Y - adfGeoTransform[3])) / dTemp + 0.5; dRow = (adfGeoTransform[1] * (sourcePoint.Y - adfGeoTransform[3]) - adfGeoTransform[4] * (sourcePoint.X - adfGeoTransform[0])) / dTemp + 0.5; int c = Convert.ToInt32(dCol); int r = Convert.ToInt32(dRow); return(ReadBand(raster, c, r)); } catch (Exception ex) { return(0); } }
private void Confirm() { if (string.IsNullOrEmpty(_rasterFilePath)) { return; } string folderPath = DialogHelper.OpenFolderDialog(true); if (!string.IsNullOrEmpty(folderPath)) { string rasterWorkSpace = Path.GetDirectoryName(_rasterFilePath); _rasterReader = new RasterReader(rasterWorkSpace, RasterFileName + ".tif"); if (WriteCityRaster(folderPath)) { Messenger.Default.Send(new GenericMessage <string>("空间可达性计算成功"), "Message"); } else { Messenger.Default.Send(new GenericMessage <string>("空间可达性计算失败"), "Message"); } } }
private bool WriteTimeCostRaster(string folderPath) { try { //读取两个文件 var landReader = new RasterReader(folderPath, LandUse + ".tif"); var roadReader = new RasterReader(folderPath, TrafficRoad + ".tif"); RasterOp landOp = new RasterOp(landReader); RasterOp roadOp = new RasterOp(roadReader); //取最小值 landOp.Overlay(roadOp, RasterAlgorithm.MinPixel); ////写入文件 RasterWriter writer = new RasterWriter(folderPath, TimeCostName, landReader.RasterInfo); landOp.WriteRaster(writer, "TIFF"); return(true); } catch (Exception e) { _log.Error(e.Message + e.StackTrace); } return(false); }
private void Run(object p) { Hashtable para = p as Hashtable; var wait = para["wait"] as ProgressWait; string folderPath = para["folderPath"].ToString(); string rasterFolderPath = Path.GetDirectoryName(_rasterFilePath); try { RasterReader reader = new RasterReader(rasterFolderPath, RasterFileName + ".tif"); int totalCount = Cities.Count(item => item.IsSelected); int count = 0; foreach (var calculatorCity in Cities) { if (calculatorCity.IsSelected) { wait.SetProgress((double)count++ / totalCount); Run(reader, calculatorCity, folderPath); GC.Collect(); } } para["ret"] = true; } catch (ArgumentOutOfRangeException e) { Messenger.Default.Send(new GenericMessage <string>("存在城市不在计算范围内"), "Exception"); para["ret"] = false; } catch (Exception e) { _log.Error(e.Message + e.StackTrace); para["ret"] = false; } finally { wait.CloseWait(); } }
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 double ReadBand(RasterReader reader, int col, int row) { double[] d = null; reader.ReadBand(col, row, 1, 1, out d); return(d[0]); }
/// <summary> /// 河网提取 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnGetHeWang_Click(object sender, EventArgs e) { if (!backgroundWorker1.IsBusy) { //获取河网参数 if (formRiver == null) { formRiver = new FormRiverArg(); } if (formRiver.ShowDialog() == DialogResult.OK) { RiverPath = formRiver.RiverPath; RiverThreshold = formRiver.RiverThreshold; FillPath = formRiver.FillPath; DirectionPath = formRiver.DirectionPath; AccumulationPath = formRiver.AccumulationPath; FormOutput.AppendLog("开始计算..."); _currentTime = DateTime.Now; SaveCaculateArg(); string srcPath = fileChooseControl1.FilePath; //已经计算过,直接从缓存读取 if (currentDem == srcPath) { RasterReader read = new RasterReader(srcPath); if (!string.IsNullOrEmpty(FillPath)) { DEMReader.SaveDem(read, fillGrid, null, FillPath); } if (!string.IsNullOrEmpty(DirectionPath)) { DEMReader.SaveDem(read, directionDev, null, DirectionPath); } if (!string.IsNullOrEmpty(AccumulationPath)) { DEMReader.SaveDem(read, Accumulation, null, AccumulationPath); } FormOutput.AppendLog("开始根据回流阀值提取河网.."); FormOutput.AppendLog($"当前阀值为{RiverThreshold}.."); RiverGrid = new int[Accumulation.GetLength(0), Accumulation.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("河网提取完成.."); FormOutput.AppendLog(string.Format("提取结束,共耗时{0}秒..", (DateTime.Now - _currentTime).TotalSeconds)); System.Diagnostics.Process.Start("Explorer.exe", Path.GetDirectoryName(RiverPath)); } else { backgroundWorker2.RunWorkerAsync(srcPath); } } } else { FormOutput.AppendLog("当前后台正在计算..."); } }
/// <summary> /// 计算当前点的最陡方向 /// 返回最陡方向的点集 /// D8算法 /// </summary> /// <param name="point"></param> /// <param name="reader"></param> /// <param name="outresult"></param> private List <Point3d> GetMaxSlopePoints(Point3d point, RasterReader reader) { double cellSizeX = reader.CellSizeX; double cellSizeY = reader.CellSizeY; int row = reader.RowCount / 50; int col = reader.ColumnCount / 50; double[] adfGeoTransform = new double[6]; reader.DataSet.GetGeoTransform(adfGeoTransform); int _maxR = 0; int _maxC = 0; List <Point3d> outresult = new List <Point3d>(); //遍历周围八个点,取最大值 List <double> dstDic = new List <double>(); for (int r = 0; r < row; r++) { for (int c = 0; c < col; c++) { double center = RasterCoefficientReader.ReadBand(reader, c, r); //东方,列+1,行不变,p(i,j)-p(i,j+1) if (c + 1 < col) { double e = center - RasterCoefficientReader.ReadBand(reader, c + 1, r); dstDic.Add(e); } else { dstDic.Add(-1); } //东南,列+1,行+1,p(i,j)-p(i+1,j+1) if (c + 1 < col && r + 1 < row) { double es = (center - RasterCoefficientReader.ReadBand(reader, c + 1, r + 1)) / Math.Sqrt(2); dstDic.Add(es); } else { dstDic.Add(-1); } //南,列+0,行+1 if (r + 1 < row) { double s = center - RasterCoefficientReader.ReadBand(reader, c, r + 1); dstDic.Add(s); } else { dstDic.Add(-1); } //西南 if (0 < c - 1 && 0 < r - 1) { double ws = (center - RasterCoefficientReader.ReadBand(reader, c - 1, r - 1)) / Math.Sqrt(2); dstDic.Add(ws); } else { dstDic.Add(-1); } //西 if (0 < c - 1) { double w = center - RasterCoefficientReader.ReadBand(reader, c - 1, r); dstDic.Add(w); } else { dstDic.Add(-1); } //西北 if (0 < c - 1 && 0 < r - 1) { double wn = (center - RasterCoefficientReader.ReadBand(reader, c - 1, r - 1)) / Math.Sqrt(2); dstDic.Add(wn); } else { dstDic.Add(-1); } //北 if (0 < r - 1) { double n = center - RasterCoefficientReader.ReadBand(reader, c, r - 1); dstDic.Add(n); } else { dstDic.Add(-1); } //东北 if (0 < r - 1 && c + 1 < col) { double en = (center - RasterCoefficientReader.ReadBand(reader, c + 1, r - 1)) / Math.Sqrt(2); dstDic.Add(en); } else { dstDic.Add(-1); } int result = 0; //判断该点水流方向 var maxTime = dstDic.Select(x => x).Max(); int dir = dstDic.FindIndex(x => x == maxTime) + 1; if (dir == 3) { result = 4;//南 _maxR = r + 1; _maxC = c; } else if (dir == 2) { result = 2;//东南 _maxR = r + 1; _maxC = c + 1; } else if (dir == 7) { result = 64;//北 _maxR = r - 1; _maxC = c; } else if (dir == 1) { result = 1;//东 _maxR = r; _maxC = c + 1; } else if (dir == 8) { result = 128;//东北 _maxR = r - 1; _maxC = c + 1; } else if (dir == 6) { result = 32;//西北 _maxR = r - 1; _maxC = c - 1; } else if (dir == 5) { result = 16;//西 _maxR = r; _maxC = c - 1; } else if (dir == 4) { result = 8;//西南 _maxR = r + 1; _maxC = c - 1; } else { result = 0; _maxR = r; _maxC = c; } double px = point.X + r * adfGeoTransform[1] + c * adfGeoTransform[2]; double py = point.Y + r * adfGeoTransform[4] + c * adfGeoTransform[5]; double pz = RasterCoefficientReader.ReadBand(reader, _maxR, _maxC);//_globeView.GetElevation(px, py); Point3d maxPoint = new Point3d(px, py, pz); outresult.Add(maxPoint); Application.DoEvents(); } /* end for c */ Application.DoEvents(); } /* enf for r */ return(outresult); }
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> /// 用于计算shp文件中的系数平均值 /// </summary> /// <param name="shppath">shp路径</param> /// <param name="inputDemPath">tif路径</param> /// <returns></returns> public static double?ReadCoeficient(string shppath, string inputDemPath) { FormOutput.AppendLog("按规定范围裁剪栅格.."); //创建一个临时目录 string outDemPath = Path.Combine(Path.GetTempPath(), "WDEM.tif"); RasterReader raster = null; Band band = null; try { ImgCut.CutTiff(shppath, inputDemPath, outDemPath); if (File.Exists(outDemPath) == false) { FormOutput.AppendLog("裁剪失败!"); return(null); } FormOutput.AppendLog("开始读取裁剪后的栅格数据.."); raster = new RasterReader(outDemPath); int row = raster.RowCount; int col = raster.ColumnCount; // int count = raster.RasterCount; int xsize = raster.DataSet.RasterXSize; int ysize = raster.DataSet.RasterYSize; band = raster.DataSet.GetRasterBand(1); //无效值 //FormOutput.AppendLog("获取栅格数据无效值.."); double nodatavalue; int hasval; band.GetNoDataValue(out nodatavalue, out hasval); // FormOutput.AppendLog("栅格数据无效值为" + nodatavalue); double[] readData = new double[row * col]; band.ReadRaster(0, 0, xsize, ysize, readData, row, col, 0, 0); //FormOutput.AppendLog("开始整理损失指数数据.."); var res = readData.GroupBy(t => t).Select(t => new { count = t.Count(), Key = t.Key }).ToArray(); double total = 0; double totalcount = 0; foreach (var s in res) { if (s.Key != nodatavalue) { total += s.Key * s.count; totalcount += s.count; } } double R = total / totalcount; R = R / 1000; //转换?? return(R); } catch (Exception ex) { FormOutput.AppendLog("获取栅格数据异常:" + ex.Message); return(null); } finally { //销毁 if (raster != null) { band.Dispose(); raster.Dispose(); } } }