Пример #1
0
        private static void CheckTreeRadius()
        {
            string problem = CTreeRadiusCalculator.IsValidEquation(CParameterSetter.GetStringSettings(ESettings.treeRadius));

            if (problem.Length > 0)
            {
                problems.Add($"tree radius equation problem: {problem}");
            }
        }
Пример #2
0
        public static string GetTooltip(ESettings pSettings)
        {
            switch (pSettings)
            {
            //buttons
            case ESettings.forestFileName:
                return(REQUIRED + "The main processed file.\n" +
                       "Read the specification of required file format in the documentation.");

            case ESettings.reftreeFolderPath:
                return(REQUIRED + "A folder containing subfolders with reftrees you want to use in the process.\n" +
                       "Read the specification of required reftree folder format in the documentation. \n" +
                       "To ignore some reftrees simply move them to folder 'ignore' or anywhere else.");

            case ESettings.outputFolderPath:
                return(REQUIRED + "Folder where an output will be exported. \n" +
                       "A subfolder with the same name as forest file will be created. If it already exists, it will have a suffix.");

            case ESettings.analyticsFilePath:
                return(OPTIONAL + "CSV file in which some analytics information about the process will be exported. \n" +
                       "If such file already exists, it will append the information to a new line. \n" +
                       "Otherwise, it will create a new file. This analytics will be also exported in the output folder.");

            case ESettings.checkTreeFilePath:
                return(OPTIONAL + "The checktree file, see the documentation for its functionality. \n" +
                       "The result of the check will be summarized in 'summary.txt' file in the output folder and visualized in a special bitmap. \n" +
                       "If you want to see a checktree result visualization on the exported model, check 'export checktrees'.");

            //bools
            case ESettings.assignRefTreesRandom:
                return("The selection of most appropriate reftree to every detected tree (the most time-consuming part of a process) is skipped and reftree is selected randomly.");

            case ESettings.useReducedReftreeModels:
                return("Use reduced file of reftree in final export. This option should be checked as the full quality model \n" +
                       "doesn't usually have that much effect on the final look and the final size is reduced greatly by using reduced models.");

            case ESettings.export3d:
                return("Export 3D models. If false -> only analytics and bitmap will be produced.");

            case ESettings.exportTreeStructures:
                return("Include tree detection structures in final export. It is only for visualisation of points assigned to trees.");

            case ESettings.exportTreeBoxes:
                return("Include simple box surrounding tree in final export. It is only for visualisation of tree extent.");

            case ESettings.colorTrees:
                return("Assign color material to trees. No neighbouring tree should have the same color. Good for visualization.");

            case ESettings.exportInvalidTrees:
                return("Include detected invalid trees in final export. Only for check if some trees which should have been detected were detected correctly.");

            case ESettings.exportRefTrees:
                return("Include reftrees in final export. \n\n" +
                       "With reftree models the size of the resulting OBJ grows rapidly and the export process takes much longer. \n" +
                       "Uncheck this only if you want to have quicker results and for result visualisation check 'exportTreeStructures'");

            case ESettings.exportPoints:
                return("Include all points in final export. Only for visualization.");

            case ESettings.filterPoints:
                return("Filters points which are too much above average height and points which do not have many points defined under them (in this case these points are probably not part of vegetation, but some unwanted source like flying animal).\n" +
                       "Use this only if you see some unwanted points in the result.");

            case ESettings.exportBitmap:
                return("Export bitmap representation of a result. Creates a) heightmap, b) tree positions and c) tree borders.");

            case ESettings.useCheckTreeFile:
                return("Loads checktree file defined above and evaluates an accuracy of the detection.");

            case ESettings.exportCheckTrees:
                return("Include checktree visualization in final export.\n\n " +
                       "Only for visualization. Correct assignment = blue, incorrect = red and invalid checktree = gray.");

            case ESettings.autoAverageTreeHeight:
                return("The average tree height is calculated automatically.\n\n" +
                       "The average height is used in tree extents calculation so it is good to have this value as close to real data as possible. " +
                       "Use this if you don't have this knowledge about the data. This option disables manual selection of a tree height.");

            //floats
            case ESettings.avgTreeHeigh:
                return("[adviced value = 10-30m] Expected average tree height in given forest file. (disabled when 'autoAverageTreeHeight' is checked)\n\n" +
                       "The average height is used in tree extents calculation so it is good to have this value as close to real data as possible. " +
                       "Use this if you have this knowledge about the data. Otherwise use 'autoAverageTreeHeight'");

            case ESettings.partitionStep:
                return("[adviced value = 20-50m] Size of on part of the final OBJ [in meters].\n\n" +
                       "Too big OBJ files are hard to handle in post-processing so it is advised to generate files with smaller sizes.\n" +
                       "All parts can be merged in a 3D editor if desired. No information is lost.");

            case ESettings.groundArrayStep:
                return("[adviced value = 1m] Size of ground array sampling [in meters].\n\n" +
                       "With smaller sampling, the reconstructed ground gets closer to real one but the processing takes much longer and it doesn't have any considerable impact on tree detection process.");

            case ESettings.treeExtent:
                return("[adviced value = 1-2 m] The maximal distance of point belonging to tree with height specified in 'average height'.\n\n" +
                       "This value grows/decreases with actual tree height in proportion to 'average tree height'. To detect trees which are very close to each other choose a smaller value. In a sparse forest, this value can be bigger.");

            case ESettings.treeExtentMultiply:
                return("[adviced value = 1,2 - 2] The multiplicator of tree extent during merging process.");

            //"\n\n" +
            //"Should result in invalid trees being attached to some higher valid tree which was too far during the first processing.";

            case ESettings.treeRadius:
                return($"Tree radius for tree with height 10m = {CTreeRadiusCalculator.GetTreeRadius(10)}\n" +
                       $"15m = {CTreeRadiusCalculator.GetTreeRadius(15)}, " +
                       $"20m = {CTreeRadiusCalculator.GetTreeRadius(20)}, " +
                       $"25m = {CTreeRadiusCalculator.GetTreeRadius(25)}");



            case ESettings.calculateAGB:
                return("Include biomass to shp attributes");

            case ESettings.calculateDBH:
                return("Include stem diameter to shp attributes");

            case ESettings.preprocess:
                return("Apply las commands: lasnoise, lasground, lasheight, lasclassify before precessing");

            case ESettings.deleteTmp:
                return("After each las command during preprocessing a tmp file is created. Check this to delete them when finished.");

            case ESettings.minTreeHeight:
                return("Minimal tree height for tree to be considered valid");

            case ESettings.minTreePoints:
                return("Minimal tree point count for tree to be considered valid");
            }

            return("- no tooltip defined");
        }
Пример #3
0
        /// <summary>
        /// Mergind method for Detection2D
        /// </summary>
        private static void Merge2DTrees()
        {
            return;

            for (int i = Trees.Count - 1; i >= 0; i--)
            {
                CTree treeToMerge = Trees[i];
                if (treeToMerge.Equals(173))
                {
                    CDebug.WriteLine();
                }

                //if(treeToMerge.IsLocalMaximum())
                //{
                //	continue;
                //}

                List <CTree> possibleTrees =
                    GetPossibleTreesToMergeWith(treeToMerge, EPossibleTreesMethod.ClosestHigher);

                for (int t = 0; t < possibleTrees.Count; t++)
                {
                    //merge trees if the target tree can be reached from the treeToMerge
                    //and they are of different heights
                    CTree tree = possibleTrees[t];

                    float maxRadius     = CTreeRadiusCalculator.GetTreeRadius(tree);
                    float treeAvgExtent = tree.GetAverageExtent();
                    float maxDist       = Math.Max(maxRadius, treeAvgExtent);

                    float treeDist = CUtils.Get2DDistance(treeToMerge, tree);
                    if (treeDist > maxDist)
                    {
                        continue;
                    }

                    /*float heightDiff = tree.GetTreeHeight() - treeToMerge.GetTreeHeight();
                     * if(heightDiff < 2)
                     * {
                     *      continue;
                     * }*/
                    bool pathContainsTree = false;

                    /*
                     * CTreeField closeField = tree.GetClosestField(treeToMerge.peak.Center);
                     * bool pathContainsTree =
                     *      CProjectData.Points.treeDetailArray.PathContainsTree(
                     *              treeToMerge.peak.Center, closeField.Center, tree, 1, 1);
                     *
                     * if(!pathContainsTree)
                     * {
                     *      pathContainsTree =
                     *        CProjectData.Points.treeDetailArray.PathContainsTree(
                     *                treeToMerge.peak.Center, tree.peak.Center, tree, 1, 1);
                     * }*/

                    bool canAdd = tree.CanAdd(treeToMerge.peak.Center, false);

                    if (pathContainsTree || canAdd)
                    {
                        treeToMerge = MergeTrees(ref treeToMerge, ref tree, true);
                        break;
                    }
                }

                /*List<CField> fields = treeToMerge.peakDetailField.GetFieldsInDistance(5);
                 * foreach(CField field in fields)
                 * {
                 *      CTreeField treeField = (CTreeField)field;
                 *      CTree detectedTree = treeField.GetSingleDetectedTree();
                 *      if(detectedTree != null && !detectedTree.Equals(treeToMerge))
                 *      {
                 *              float heightDiff = detectedTree.GetTreeHeight() - treeToMerge.GetTreeHeight();
                 *              if(heightDiff > 2)
                 *              {
                 *                      treeToMerge = MergeTrees(ref treeToMerge, ref detectedTree, true);
                 *                      break;
                 *              }
                 *      }
                 * }*/
            }
        }
Пример #4
0
        public static EProcessResult Start()
        {
            CSequenceController.SetValues();

            DateTime startTime = DateTime.Now;

            CProjectData.Init();
            CTreeManager.Init();
            CAnalytics.Init();

            CDartTxt.Init();
            CLasExporter.Init();
            CBiomassController.Init(
                CParameterSetter.GetStringSettings(ESettings.dbh),
                CParameterSetter.GetStringSettings(ESettings.agb));
            CTreeRadiusCalculator.Init();
            CShpController.Init();
            CReftreeManager.Init();

            Thread.CurrentThread.CurrentCulture = new CultureInfo("en");

            //GENERAL
            CProjectData.useMaterial     = true;
            CObjExporter.simplePointsObj = false;

            CMaterialManager.Init();

            string[] workerResult = new string[2];
            workerResult[0] = "this string";
            workerResult[1] = "some other string";
            CProjectData.backgroundWorker.ReportProgress(10, workerResult);

            try
            {
                List <string> tiledFiles = CProgramLoader.GetTiledPreprocessedFilePaths();

                tilesCount = tiledFiles.Count;
                int startTile = CParameterSetter.GetIntSettings(ESettings.startIndex);
                if (startTile < 0 || startTile >= tiledFiles.Count)
                {
                    throw new Exception($"Parameter startTile = {startTile}, tiledFiles.Count = {tiledFiles.Count}");
                }

                for (int i = startTile; i < tiledFiles.Count; i++)
                {
                    string         tiledFilePath = tiledFiles[i];
                    EProcessResult tileProcess   = ProcessTile(tiledFilePath, i);
                    if (CProjectData.backgroundWorker.CancellationPending)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                CDebug.Error(
                    $"{Environment.NewLine}exception: {e.Message} {Environment.NewLine}{Environment.NewLine}" +
                    $"StackTrace: {e.StackTrace}{Environment.NewLine}");
                OnException();
                return(EProcessResult.Exception);
            }

            if (CProjectData.backgroundWorker.CancellationPending)
            {
                CDebug.Step(EProgramStep.Cancelled);
                return(EProcessResult.Cancelled);
            }

            CDebug.Step(EProgramStep.ExportMainFiles);
            //TODO: implement this in super class for all controllers
            //dont create the main file if not needed
            if (tilesCount > 1)
            {
                CDartTxt.ExportMain();
                CLasExporter.ExportMain();
                CShpController.ExportMain();
            }
            CBitmapExporter.ExportMain();

            CDebug.Step(EProgramStep.Done);

            if (CSequenceController.IsLastSequence())
            {
                CSequenceController.OnLastSequenceEnd();
                return(EProcessResult.Done);
            }

            CSequenceController.currentConfigIndex++;
            return(Start());
        }