/// <summary> /// 基于气象因子的白桦天然林单木直径生长模型(张海平,2017) /// minTg:生长季最低气温; meanPg:生长季平均降水量 /// </summary> /// <param name="units"></param> /// <param name="dem"></param> /// <param name="param"></param> /// <param name="minTg"></param> /// <param name="meanPg"></param> /// <returns></returns> public List <Tree> DBHGrowthModel3(List <SpatialUnit.unit_tree> units, DEMOperate dem, List <double> param, double minTg, double meanPg, double area) { //BAS 每公顷断面积 double BA = 0; for (int i = 0; i < array.Count; i++) { BA = BA + Math.PI * array[i].DBH * array[i].DBH / 4; } double BAS = BA / area; //BAL 大于对象木全部树木胸高断面积之和 List <double> BAL = new List <double>(); for (int i = 0; i < array.Count; i++) { double bal = 0; for (int j = 0; j < array.Count; j++) { if (array[j].DBH > array[i].DBH) { bal = bal + Math.PI * array[j].DBH * array[j].DBH / 4; } } BAL.Add(bal / 10000); } for (int i = 0; i < array.Count; i++) { //林木个体 double size = param[1] * Math.Log(array[i].DBH) + param[2] * array[i].DBH * array[i].DBH; //竞争 double comp = param[3] * BAS + param[4] * BAL[i] / array[i].DBH; //气象因子 double clim = param[5] * minTg + param[6] * meanPg; double DGI = Math.Exp(param[0] + size + comp + clim) - 1; array[i].DBH = Math.Sqrt(array[i].DBH * array[i].DBH + DGI); if (Double.IsNaN(array[i].DBH) || Double.IsInfinity(array[i].DBH)) { Console.WriteLine("ERROR: NaN or Infinity of DBH"); return(null); } } return(array); }
/// <summary> /// Hynynen, 1995 /// </summary> /// <param name="array"></param> /// <param name="param"></param> /// <returns></returns> public List <Tree> InvokeUBHModels(List <Tree> array, List <double> param, double area, DEMOperate dem) { //BAS 每公顷断面积 double BA = 0; for (int i = 0; i < array.Count; i++) { BA = BA + Math.PI * array[i].DBH * array[i].DBH / 4; } BA = BA / area; //BAL 大于对象木全部树木胸高断面积之和 List <double> BAL = new List <double>(); for (int i = 0; i < array.Count; i++) { double bal = 0; for (int j = 0; j < array.Count; j++) { if (array[j].DBH > array[i].DBH) { bal = bal + Math.PI * array[j].DBH * array[j].DBH / 4; } } BAL.Add(bal / 10000); } //优势高 array.Sort((left, right) => - left.Height.CompareTo(right.Height)); double[] domainHeight = new double[5]; for (int j = 0; j < 5; j++) { domainHeight[j] = array[j].Height; } double DH = domainHeight.Average(); //按ID排序,升序 array.Sort((left, right) => left.ID.CompareTo(right.ID)); //计算枝下高 for (int i = 0; i < array.Count; i++) { //计算x,y对应DEM的行列号 dem.getColRow(array[i].X, array[i].Y); //读取高程 double altitude = dem.getDEMValue(); //计算坡度 double slope = dem.CalcuSlope(); //计算坡向 double aspect = dem.CalcuAspect(); double X = param[0] + param[1] * array[i].Height / array[i].DBH + param[2] * array[i].Height + param[3] * array[i].DBH * array[i].DBH + param[4] * BAL[i] + param[5] * altitude / 100 + param[6] * altitude * altitude / 10000 + param[7] * Math.Tan(slope) + param[8] * Math.Tan(slope) * Math.Tan(slope) + param[9] * slope *Math.Sin(aspect) + param[10] * slope *Math.Cos(aspect); double CR = 1 / (1 + Math.Exp(-X)); array[i].UnderBranchHeight = (1 - CR) * array[i].Height; if (Double.IsNaN(array[i].UnderBranchHeight) || Double.IsInfinity(array[i].UnderBranchHeight)) { Console.WriteLine("ERROR: NaN or Infinity of UnderBranchHeight"); return(null); } } return(array); }
/// <summary> /// Sönmez 2009, A distance-independent basal area growth model for oriental spruce... /// 针对混合混交林,对于纯林同样适用 /// </summary> /// <param name="units"></param> /// <param name="dem"></param> /// <param name="param"></param> /// <param name="SI"></param> /// <param name="age"></param> /// <returns></returns> public List <Tree> DBHGrowthModel5(List <SpatialUnit.unit_tree> units, DEMOperate dem, List <double> param, double SI, double age, double area, double BP) { //BAS 每公顷断面积 double BA = 0; for (int i = 0; i < array.Count; i++) { BA = BA + Math.PI * array[i].DBH * array[i].DBH / 4; } BA = BA / area; double N = array.Count / area * 10000; //BAL 大于对象木全部树木胸高断面积之和 List <double> BAL = new List <double>(); for (int i = 0; i < array.Count; i++) { double bal = 0; for (int j = 0; j < array.Count; j++) { if (array[j].DBH > array[i].DBH) { bal = bal + Math.PI * array[j].DBH * array[j].DBH / 4; } } BAL.Add(bal / 10000); } for (int i = 0; i < array.Count; i++) { //个体参数 double size = param[1] * Math.Log(array[i].DBH) + param[2] * array[i].DBH * array[i].DBH + param[3] / age; //竞争 double comp = param[4] * BAL[i] + param[5] * Math.Log(BA) + param[6] * Math.Log(N); //计算x,y对应DEM的行列号 dem.getColRow(array[i].X, array[i].Y); //读取高程 double altitude = dem.getDEMValue(); //计算坡度 double slope = dem.CalcuSlope(); //计算坡向 double aspect = dem.CalcuAspect(); //立地 double site = param[7] * SI + param[8] * altitude + param[9] * Math.Log(aspect * 180 / Math.PI + 1); //混交 double mix = param[10] * Math.Log(BP + 1); double DGI = Math.Exp(param[0] + size + comp + site); array[i].DBH = 2 * Math.Sqrt((Math.PI * array[i].DBH * array[i].DBH / 4 + DGI) / Math.PI); if (Double.IsNaN(array[i].DBH) || Double.IsInfinity(array[i].DBH)) { Console.WriteLine("ERROR: NaN or Infinity of DBH"); return(null); } } return(array); }
/// <summary> /// 蒙古栎天然林单木生长模型研究(马武,2015) /// </summary> /// <param name="units"></param> /// <param name="dem"></param> /// <param name="param">param16:林分密度指数参数</param> /// <param name="canopydensity">郁闭度</param> /// <param name="SI">地位指数</param> /// <param name="D0">标准平均直径(中国一般取10)</param> /// <returns></returns> public List <Tree> DBHGrowthModel4(List <SpatialUnit.unit_tree> units, DEMOperate dem, List <double> param, double canopydensity, double SI, double D0, double area) { //林分每公顷断面积 double BA = 0; for (int i = 0; i < array.Count; i++) { BA = BA + Math.PI * array[i].DBH * array[i].DBH / 4; } double BAS = BA / area; //BAL 大于对象木全部树木胸高断面积之和 List <double> BAL = new List <double>(); for (int i = 0; i < array.Count; i++) { double bal = 0; for (int j = 0; j < array.Count; j++) { if (array[j].DBH > array[i].DBH) { bal = bal + Math.PI * array[j].DBH * array[j].DBH / 4; } } BAL.Add(bal / 10000); } //林分中最大直径 double maxDBH = array[0].DBH; for (int i = 0; i < array.Count; i++) { if (maxDBH < array[i].DBH) { maxDBH = array[i].DBH; } } for (int i = 0; i < array.Count; i++) { //林木个体 double size = param[1] * Math.Log(array[i].DBH) + param[2] * array[i].DBH * array[i].DBH; //林分密度指数 double N = array.Count / area * 10000; double SDI = N * Math.Pow(D0 / array[i].DBH, param[17]); //对象木胸径与林分断面积平均胸径之比RD double RD = array[i].DBH / (Math.Sqrt((BA / array.Count) / Math.PI) * 2); //林分中大于对象木的所有林木直径平方和DL double DL = 0; for (int j = 0; j < array.Count; j++) { if (array[j].DBH > array[i].DBH) { DL = DL + array[j].DBH * array[j].DBH; } } //对象木直径与林分中最大林木直径之比DDM double DDM = array[i].DBH / maxDBH; //竞争 double comp = param[3] * BAL[i] + param[4] * SDI + param[5] * BAS + param[6] * RD + param[7] * DL + param[8] * canopydensity + param[9] * DDM; //立地条件 //计算x,y对应DEM的行列号 dem.getColRow(array[i].X, array[i].Y); //读取高程 double altitude = dem.getDEMValue(); //计算坡度 double slope = dem.CalcuSlope(); //计算坡向 double aspect = dem.CalcuAspect(); double SL = Math.Tan(slope); double E = altitude; double SLS = SL * Math.Sin(aspect); double SLC = SL * Math.Cos(aspect); double site = param[10] * SI + param[11] * SL + param[12] * SL * SL + param[13] * E + param[14] * E * E + param[15] * SLS + param[16] * SLC; double DGI = Math.Exp(param[0] + size + comp + site); array[i].DBH = Math.Sqrt(array[i].DBH * array[i].DBH + DGI); if (Double.IsNaN(array[i].DBH) || Double.IsInfinity(array[i].DBH)) { Console.WriteLine("ERROR: NaN or Infinity of DBH"); return(null); } } return(array); }
/// <summary> /// 基于简单竞争指数胸径连年生长量模型(覃阳平)——胸径 /// param 0~7:模型参数;param 8~10:竞争指数参数 /// </summary> /// <param name="units"></param> /// <param name="dem"></param> /// <param name="param"></param> /// <param name="SI"></param> /// <returns></returns> public List <Tree> DBHGrowthModel1(List <SpatialUnit.unit_tree> units, DEMOperate dem, List <double> param, double SI) { //double avgDBH = 0; //int count = 0; List <double> D = new List <double>(); for (int i = 0; i < array.Count; i++) { //胸径增长量 double DGI = 0; //计算x,y对应DEM的行列号 dem.getColRow(array[i].X, array[i].Y); //读取高程 double altitude = dem.getDEMValue(); //计算坡度 double slope = dem.CalcuSlope(); //计算坡向 double aspect = dem.CalcuAspect(); //生长模型 //计算胸径增长量 //计算林木大小因子 double size = param[1] * Math.Log(array[i].DBH) + param[2] * array[i].DBH * array[i].DBH; //计算竞争因子 double distance1 = Math.Sqrt((array[units[i].id[0]].X - array[i].X) * (array[units[i].id[0]].X - array[i].X) + (array[units[i].id[0]].Y - array[i].Y) * (array[units[i].id[0]].Y - array[i].Y)); double comp1 = (Math.Pow(array[units[i].id[0]].DBH, param[8]) / Math.Pow(array[i].DBH, param[9])) / Math.Pow(distance1, param[10]); double distance2 = Math.Sqrt((array[units[i].id[1]].X - array[i].X) * (array[units[i].id[1]].X - array[i].X) + (array[units[i].id[1]].Y - array[i].Y) * (array[units[i].id[1]].Y - array[i].Y)); double comp2 = (Math.Pow(array[units[i].id[1]].DBH, param[8]) / Math.Pow(array[i].DBH, param[9])) / Math.Pow(distance2, param[10]); double distance3 = Math.Sqrt((array[units[i].id[2]].X - array[i].X) * (array[units[i].id[2]].X - array[i].X) + (array[units[i].id[2]].Y - array[i].Y) * (array[units[i].id[2]].Y - array[i].Y)); double comp3 = (Math.Pow(array[units[i].id[2]].DBH, param[8]) / Math.Pow(array[i].DBH, param[9])) / Math.Pow(distance3, param[10]); double distance4 = Math.Sqrt((array[units[i].id[3]].X - array[i].X) * (array[units[i].id[3]].X - array[i].X) + (array[units[i].id[3]].Y - array[i].Y) * (array[units[i].id[3]].Y - array[i].Y)); double comp4 = (Math.Pow(array[units[i].id[3]].DBH, param[8]) / Math.Pow(array[i].DBH, param[9])) / Math.Pow(distance4, param[10]); double comp = comp1 + comp2 + comp3 + comp4; //计算立地条件 double site = param[4] * SI + param[5] * Math.Tan(slope) + param[6] * altitude + param[7] * aspect * 180 / Math.PI; //胸径增长量 DGI = Math.Exp(param[0] + size + param[3] * comp + site); double tempD = Math.Sqrt(DGI + array[i].DBH * array[i].DBH); array[i].DBH = tempD; if (Double.IsNaN(array[i].DBH) || Double.IsInfinity(array[i].DBH)) { Console.WriteLine("ERROR: NaN or Infinity of DBH"); return(null); } } ////边界木变化取平均值 //if (count > 0) //{ // avgDBH = avgDBH / count; // for (int i = 0; i < array.Count; i++) // { // if (array[i].isEdge) // { // array[i].DBH = avgDBH; // } // } //} return(array); }
/// <summary> /// 基于树冠竞争因子的落叶松人工林单木生长模型(刘强)——断面积 /// param 0~10:模型参数;param 11:林分密度指数参数 /// </summary> /// <param name="units"></param> /// <param name="dem"></param> /// <param name="param"></param> /// <param name="D0">标准平均直径(中国一般取10)</param> /// <returns></returns> public List <Tree> DBHGrowthModel2(List <SpatialUnit.unit_tree> units, DEMOperate dem, List <double> param, double D0, double area) { //林木大小 double Dg = 0; List <double> AREA = new List <double>(); double avgA = 0; int count = 0; //林分平均直径 for (int i = 0; i < array.Count; i++) { Dg = Dg + Math.PI * array[i].DBH * array[i].DBH / 4; } Dg = Math.Sqrt(Dg / array.Count / Math.PI) * 2; for (int i = 0; i < array.Count; i++) { if (!array[i].isEdge) { double size = param[1] * Math.Log(array[i].DBH) + param[2] * array[i].DBH * array[i].DBH + param[3] * Dg; //Hegyi竞争指数 double distance1 = Math.Sqrt((array[units[i].id[0]].X - array[i].X) * (array[units[i].id[0]].X - array[i].X) + (array[units[i].id[0]].Y - array[i].Y) * (array[units[i].id[0]].Y - array[i].Y)); double comp1 = (array[units[i].id[0]].DBH / array[i].DBH) / distance1; double distance2 = Math.Sqrt((array[units[i].id[1]].X - array[i].X) * (array[units[i].id[1]].X - array[i].X) + (array[units[i].id[1]].Y - array[i].Y) * (array[units[i].id[1]].Y - array[i].Y)); double comp2 = (array[units[i].id[1]].DBH / array[i].DBH) / distance2; double distance3 = Math.Sqrt((array[units[i].id[2]].X - array[i].X) * (array[units[i].id[2]].X - array[i].X) + (array[units[i].id[2]].Y - array[i].Y) * (array[units[i].id[2]].Y - array[i].Y)); double comp3 = (array[units[i].id[2]].DBH / array[i].DBH) / distance3; double distance4 = Math.Sqrt((array[units[i].id[3]].X - array[i].X) * (array[units[i].id[3]].X - array[i].X) + (array[units[i].id[3]].Y - array[i].Y) * (array[units[i].id[3]].Y - array[i].Y)); double comp4 = (array[units[i].id[3]].DBH / array[i].DBH) / distance4; double CI = comp1 + comp2 + comp3 + comp4; //对象木冠面积 double C = CrownArea(i); //树冠竞争指数 double CI1 = CrownArea(units[i].id[0]) / CrownArea(i) / distance1 + CrownArea(units[i].id[1]) / CrownArea(i) / distance2 + CrownArea(units[i].id[2]) / CrownArea(i) / distance3 + CrownArea(units[i].id[3]) / CrownArea(i) / distance4; double CI2 = (CrownArea(units[i].id[0]) + CrownArea(i)) / CrownArea(i) / distance1 + (CrownArea(units[i].id[1]) + CrownArea(i)) / CrownArea(i) / distance2 + (CrownArea(units[i].id[2]) + CrownArea(i)) / CrownArea(i) / distance3 + (CrownArea(units[i].id[3]) + CrownArea(i)) / CrownArea(i) / distance4; //林分密度指数 double N = array.Count / area * 10000; double SDI = N * Math.Pow(D0 / array[i].DBH, param[11]); double comp = param[4] * array[i].Height + param[5] * array[i].UnderBranchHeight + param[6] * C + param[7] * CI + param[8] * CI1 + param[9] * CI2 + param[10] * SDI; double AGI = Math.Exp(param[0] + size + comp); double tempA = AGI + Math.PI * (array[i].DBH * array[i].DBH / 4); AREA.Add(tempA); if (Double.IsNaN(tempA) || Double.IsInfinity(tempA)) { Console.WriteLine("ERROR: NaN or Infinity of DBH"); return(null); } avgA += tempA; count++; } } //边界木变化取平均值 if (count > 0) { avgA = avgA / count; for (int i = 0; i < array.Count; i++) { if (array[i].isEdge) { AREA[i] = avgA; } } } //更新胸径 for (int i = 0; i < array.Count; i++) { array[i].DBH = Math.Sqrt(AREA[i] / Math.PI) * 2; } return(array); }
/// <summary> /// LP Leites (2009) Logistic型 /// </summary> /// <param name="array"></param> /// <param name="param"></param> /// <returns></returns> public List <Tree> InvokeUBHModels(List <Tree> array, List <double> param, double area, DEMOperate dem) { //BAS 每公顷断面积 double BA = 0; for (int i = 0; i < array.Count; i++) { BA = BA + Math.PI * array[i].DBH * array[i].DBH / 4; } BA = BA / area; //计算冠高 for (int i = 0; i < array.Count; i++) { double CR = 1 / (1 + Math.Exp(param[0] + param[1] * array[i].DBH + param[2] * array[i].Height + param[3] * BA)); array[i].UnderBranchHeight = (1 - CR) * array[i].Height; if (Double.IsNaN(array[i].UnderBranchHeight) || Double.IsInfinity(array[i].UnderBranchHeight)) { Console.WriteLine("ERROR: NaN or Infinity of UnderBranchHeight"); return(null); } } return(array); }