示例#1
0
文件: Forest.cs 项目: TsaiYoung/iSGMS
        public List <Tree> createTrees(DEMOperate dem, int i)
        {
            trees      = forestShp.createTreePosition(dem, i);
            forestArea = forestShp.GetForestArea();

            return(trees);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
        }