public List <Tree> createTrees(DEMOperate dem, int i) { trees = forestShp.createTreePosition(dem, i); forestArea = forestShp.GetForestArea(); return(trees); }
/// <summary> /// 创建树木位置 /// </summary> public List <Tree> createTreePosition(DEMOperate dem, int i) { Console.WriteLine("Create trees of feature " + i); if (oLayer == null) { return(null); } string forestType = "人工林"; string distributeType = ""; double density = 0; double standArea = 0; double treeNum = 0; double D = 0, Dg = 0; List <Tree> trees = new List <Tree>(); Feature oFeature = oLayer.GetFeature(i); // 获得森林类型 for (int iField = 0; iField < m_FeildList.Count; iField++) { if (m_FeildList[iField].ToUpper() == "F_QIYUAN" || m_FeildList[iField].ToUpper() == "TYPE" || m_FeildList[iField].ToUpper() == "FOREST_TYPE" || m_FeildList[iField].ToUpper() == "STAND_TYPE") { forestType = GetFeildContent(iField, oFeature); } if (m_FeildList[iField].ToUpper() == "F_DWZS" || m_FeildList[iField].ToUpper() == "DENSITY" || m_FeildList[iField].ToUpper() == "FOREST_DENSITY" || m_FeildList[iField].ToUpper() == "STAND_DENSITY") { density = Convert.ToDouble(GetFeildContent(iField, oFeature)); } if (m_FeildList[iField].ToUpper() == "DISTRIBUTE" || m_FeildList[iField].ToUpper() == "F_FBLX") { distributeType = GetFeildContent(iField, oFeature); } if (m_FeildList[iField].ToUpper() == "MEAN_DBH")//算数平均胸径 { D = Convert.ToDouble(GetFeildContent(iField, oFeature)); } if (m_FeildList[iField].ToUpper() == "QUADRATIC_MEAN_DBH" || m_FeildList[iField].ToUpper() == "Q_MEAN_DBH")//平均胸径(二次平均胸径) { Dg = Convert.ToDouble(GetFeildContent(iField, oFeature)); } if (m_FeildList[iField].ToUpper() == "F_ZHUSHU" || m_FeildList[iField].ToUpper() == "TREE_NUMBER" || m_FeildList[iField].ToUpper() == "TREENUMBER")//林木数量 { treeNum = Convert.ToDouble(GetFeildContent(iField, oFeature)); } } if (density == 0) { if (treeNum != 0) { standArea = oFeature.GetGeometryRef().GetArea(); density = treeNum / standArea / 10000; } else { Console.WriteLine("DATA ERROR: The Stand density is lacked."); return(null); } } // 人工林 if (forestType == "人工林" || forestType == "Plantation") { Geometry geom = oFeature.GetGeometryRef(); Envelope env = new Envelope(); geom.GetEnvelope(env); //分布范围 double xMax, xMin, yMax, yMin, xCen, yCen; xMax = env.MaxX; xMin = env.MinX; yMax = env.MaxY; yMin = env.MinY; xCen = (xMax + xMin) / 2; yCen = (yMax + yMin) / 2; //将值放入泛型当中位置坐标 List <double> tempX = new List <double>(); List <double> tempY = new List <double>(); double sideLength = Math.Sqrt(density / 10000 * ((xMax - xMin) * (yMax - yMin)));//边长 double offsetX = (xMax - xMin) / sideLength; double offsetY = (yMax - yMin) / sideLength; double diagonal = Math.Sqrt((xMax - xMin) * (xMax - xMin) + (yMax - yMin) * (yMax - yMin)); //对角线 double xAdd = (diagonal - (xMax - xMin)) / 2; double yAdd = (diagonal - (yMax - yMin)) / 2; Random rand = new Random(); //菱形均匀分布 if (distributeType.Contains("Diamond") || distributeType.Contains("Interlaced")) { Console.WriteLine("Diamond distribution"); int row = 0; for (double j = xMin - xAdd; j < xMax + xAdd; j += offsetX) { if (row % 2 == 0) { for (double k = yMin - yAdd; k < yMax + yAdd; k += offsetY) { tempX.Add(j + rand.Next(10) / 10.0 * offsetX / 4); tempY.Add(k + rand.Next(10) / 10.0 * offsetY / 4); } } else { for (double k = yMin - yAdd + offsetY / 2; k < yMax + yAdd; k += offsetY) { tempX.Add(j + rand.Next(10) / 10.0 * offsetX / 4); tempY.Add(k + rand.Next(10) / 10.0 * offsetY / 4); } } row++; } } // 环形均匀分布 else if (distributeType.Contains("Circular")) { Console.WriteLine("Circular distribution"); //对角线做直径,计算面积,计算株数,计算环数,计算环距,计算极坐标,计算xy double r = diagonal / 2; double A = Math.PI * r * r; double N = density / 10000 * A; int roundNum = (int)((Math.Sqrt(1 + 4.0 / 3 * N) - 1) / 2); double roundDistance = Math.Sqrt(A / Math.PI) / roundNum; for (int j = 0; j < roundNum; j++) { double radius = j * roundDistance; //极矩 for (int k = 0; k < 6 * j; k++) { double angle = k * 2 * Math.PI / 6 / j; //极径 tempX.Add(radius * Math.Cos(angle) + rand.Next(10) / 10.0 * roundDistance / 4 + xCen + rand.Next(10) / 10.0 * roundDistance / 4); tempY.Add(radius * Math.Sin(angle) + rand.Next(10) / 10.0 * roundDistance / 4 + yCen + rand.Next(10) / 10.0 * roundDistance / 4); } } } // 井型均匀分布 else if (distributeType.Contains("Rectangular")) { Console.WriteLine("Rectangular distribution"); for (double j = xMin - xAdd; j < xMax + xAdd; j += offsetX) { for (double k = yMin - yAdd; k < yMax + yAdd; k += offsetY) { tempX.Add(j + rand.Next(10) / 10.0 * offsetX / 4); tempY.Add(k + rand.Next(10) / 10.0 * offsetY / 4); } } } else { Console.WriteLine("Rectangular distribution (default)"); // 默认井型 for (double j = xMin - xAdd; j < xMax + xAdd; j += offsetX) { for (double k = yMin - yAdd; k < yMax + yAdd; k += offsetY) { tempX.Add(j + rand.Next(10) / 10.0 * offsetX / 4); tempY.Add(k + rand.Next(10) / 10.0 * offsetY / 4); } } } //计算林分坡度 dem.getColRow(xCen, yCen); double aspect = dem.CalcuAspect(); //坐标系转换,林木沿山坡分布 for (int j = 0; j < tempX.Count; j++) { double x = (tempX[j] - xCen) * Math.Cos(aspect) + (tempY[j] - yCen) * Math.Sin(aspect); double y = (tempY[j] - yCen) * Math.Cos(aspect) - (tempX[j] - xCen) * Math.Sin(aspect); tempX[j] = x + xCen; tempY[j] = y + yCen; } //用此Driver创建Shape文件 //创建DataSource string temppath = "temp" + i + ".shp"; DataSource pDataSource = oDriver.CreateDataSource(temppath, null); if (pDataSource == null) { Console.WriteLine("DataSource Creation Error"); } //创建层Layer string outname = "point_out" + i; Layer tempLayer = pDataSource.CreateLayer(outname, null, wkbGeometryType.wkbPoint, null); if (tempLayer == null) { Console.WriteLine("Layer Creation Failed"); } //创建属性 FieldDefn oField1 = new FieldDefn("TREE_ID", FieldType.OFTInteger); oField1.SetWidth(16); tempLayer.CreateField(oField1, 1); //创建一个Feature Feature mFeature = new Feature(tempLayer.GetLayerDefn()); // 创建点 Geometry mPoint = new Geometry(wkbGeometryType.wkbPoint); for (int j = 0; j < tempX.Count; j++) { //树木编号 mFeature.SetField(0, j); //添加坐标点 mPoint.AddPoint(tempX[j], tempY[j], 0); mFeature.SetGeometry(mPoint); //将带有坐标及属性的Feature要素点写入Layer中 tempLayer.CreateFeature(mFeature); } //关闭文件读写 mFeature.Dispose(); mPoint.Dispose(); //创建裁切Layer string clipLyrname = "ClipLayer" + i; Layer clipLayer = pDataSource.CreateLayer(clipLyrname, null, wkbGeometryType.wkbPolygon, null); clipLayer.CreateFeature(oFeature); //裁剪 string treePosition = "treePosition" + i; Layer result = pDataSource.CreateLayer(treePosition, null, wkbGeometryType.wkbPoint, null); tempLayer.Clip(clipLayer, result, new string[] { "SKIP_FAILURES=YES" }, null, null); // 删除临时temp.shp tempLayer.Dispose(); pDataSource.DeleteLayer(0); //以下读取数据并对trees赋值 int rFeatureCount = (int)result.GetFeatureCount(0); Feature rFeature = null; for (int k = 0; k < rFeatureCount; k++) { Tree tree = new Tree(); tree.ForestID = i; //标注所属树林 tree.ID = k; //树木编号 rFeature = result.GetFeature(k); Geometry geometry = rFeature.GetGeometryRef(); tree.X = geometry.GetX(0); tree.Y = geometry.GetY(0); trees.Add(tree);//加入trees } Console.WriteLine("Get trees' locations"); //求算WVA,WVA表示采用加权Voronoi图得出每株数的多边形面积 List <double> boundX = new List <double>(); List <double> boundY = new List <double>(); boundX.Add(xMin - offsetX); boundX.Add(xMin - offsetX); boundX.Add(xMax + offsetX); boundX.Add(xMax + offsetX); boundY.Add(yMin - offsetY); boundY.Add(yMax + offsetY); boundY.Add(yMax + offsetY); boundY.Add(yMin - offsetY); Geometry oGeometry = new Geometry(wkbGeometryType.wkbPolygon); List <double> treeX = new List <double>(); List <double> treeY = new List <double>(); List <double> Area = new List <double>(); for (int t = 0; t < trees.Count; t++) { //只在本树林范围计算WVA,此时tree_count为除本树林已加入trees的棵数 treeX.Add(trees[t].X); treeY.Add(trees[t].Y); Area.Add(0); //初始化 } int t_num = trees.Count; //此树林树木棵数 double[] treex = treeX.ToArray(); double[] treey = treeY.ToArray(); double[] boundx = boundX.ToArray(); double[] boundy = boundY.ToArray(); double[] area = Area.ToArray(); CreateThiessen(treex, treey, t_num, boundx, boundy, 4, area); for (int t = 0; t < trees.Count; t++) { trees[t].WVA = area[t]; } //分配胸径 WeibullDistribute(trees, trees.Count, D, Dg); // 删除临时 clipLayer.Dispose(); result.Dispose(); pDataSource.DeleteLayer(0); pDataSource.DeleteLayer(0); } return(trees); }
/// <summary> /// 计算胸径 /// </summary> /// <param name="array"></param> /// <param name="units"></param> /// <param name="dem"></param> /// <param name="forest"></param> /// <param name="param"></param> /// <param name="age"></param> /// <param name="SI"></param> /// <param name="D0"></param> /// <param name="minTg"></param> /// <param name="meanPg"></param> /// <param name="canopydensity"></param> /// <returns></returns> List <Tree> CalcuDBH(List <Tree> array, List <SpatialUnit.unit_tree> units, DEMOperate dem, List <double> param, int age, double forestArea, double SI, double D0, double minTg, double meanPg, double canopydensity, int MT, int VT, double TS, double BP) { modelLibrary.DBHmodels.DBHGrowthModelSet dbh = new modelLibrary.DBHmodels.DBHGrowthModelSet(array); switch (DBHmodeltype) { case (int)enDBHmodels.QinModel: array = dbh.DBHGrowthModel1(units, dem, param, SI); break; case (int)enDBHmodels.LiuModel: array = dbh.DBHGrowthModel2(units, dem, param, D0, forestArea); break; case (int)enDBHmodels.ZhangModel: array = dbh.DBHGrowthModel3(units, dem, param, minTg, meanPg, forestArea); break; case (int)enDBHmodels.MaModel: array = dbh.DBHGrowthModel4(units, dem, param, canopydensity, SI, D0, forestArea); break; case (int)enDBHmodels.SonmezModel: array = dbh.DBHGrowthModel5(units, dem, param, SI, age, forestArea, BP); break; case (int)enDBHmodels.PukkalaModel: array = dbh.DBHGrowthModel6(param, forestArea, MT, VT, TS); break; case (int)enDBHmodels.CampoModel: array = dbh.DBHGrowthModel7(param, forestArea, age); break; case (int)enDBHmodels.MabvuriraModel1: array = dbh.DBHGrowthModel8(param, forestArea, age); break; case (int)enDBHmodels.MabvuriraModel2: array = dbh.DBHGrowthModel9(param, forestArea, age); break; case (int)enDBHmodels.DengModel1: array = dbh.DBHGrowthModel10(param, forestArea, age, SI); break; case (int)enDBHmodels.DengModel2: array = dbh.DBHGrowthModel11(param, forestArea, age, SI); break; case (int)enDBHmodels.DengModel3: array = dbh.DBHGrowthModel12(param, forestArea, age, SI); break; case (int)enDBHmodels.DengModel4: array = dbh.DBHGrowthModel13(param, forestArea, age, SI); break; case (int)enDBHmodels.DengModel5: array = dbh.DBHGrowthModel14(param, forestArea, age, SI); break; case (int)enDBHmodels.ZengModel: array = dbh.DBHGrowthModel15(param, forestArea, age, SI); break; case (int)enDBHmodels.LvModel: array = dbh.DBHGrowthModel16(param, forestArea, SI); break; } return(array); }