コード例 #1
0
        /// <summary>
        /// Assigns vege poins to trees. Handled in TreeManager
        /// </summary>
        private void ProcessVegePoints()
        {
            vege.Sort((b, a) => a.Z.CompareTo(b.Z));             //sort descending by height

            const int debugFrequency = 10000;

            DateTime processVegePointsStart = DateTime.Now;

            CDebug.WriteLine("ProcessVegePoints", true);

            DateTime previousDebugStart = DateTime.Now;


            int pointsToAddCount = vege.Count;

            //pointsToAddCount = 12000;

            for (int i = 0; i < pointsToAddCount; i++)
            {
                if (CProjectData.backgroundWorker.CancellationPending)
                {
                    return;
                }

                Vector3 point = vege[i];
                CTreeManager.AddPoint(point, i);

                CDebug.Progress(i, vege.Count, debugFrequency, ref previousDebugStart, processVegePointsStart, "added point");
            }
            CDebug.WriteLine("maxPossibleTreesAssignment = " + CTreeManager.maxPossibleTreesAssignment + " todo: investigate if too high");


            CAnalytics.processVegePointsDuration = CAnalytics.GetDuration(processVegePointsStart);
            CDebug.Duration("ProcessVegePoints", processVegePointsStart);
        }
コード例 #2
0
        public static void ExportTile()
        {
            if (!export)
            {
                return;
            }
            DateTime exportStart = DateTime.Now;

            StringBuilder output = new StringBuilder();
            string        res;

            DateTime start     = DateTime.Now;
            DateTime lastDebug = DateTime.Now;

            AddPointsTo(ref output, EClass.Unassigned, ref start);
            AddPointsTo(ref output, EClass.Ground, ref start);
            AddPointsTo(ref output, EClass.Building, ref start);

            if (CTreeManager.GetDetectMethod() == EDetectionMethod.Balls)
            {
                AddPointsTo(ref output, EClass.BallsSurface, ref start);
                AddPointsTo(ref output, EClass.Balls, ref start);
                AddPointsTo(ref output, EClass.BallsMainPoints, ref start);
                AddPointsTo(ref output, EClass.BallsCenters, ref start);
            }

            //tree points
            AddTreePointsTo(ref output, true, ref start);
            //invalid tree points
            AddTreePointsTo(ref output, false, ref start);

            if (output.Length == 0)
            {
                CDebug.Warning($"CLasExporter: no output created on tile {CProgramStarter.currentTileIndex}");
                return;
            }

            //1. Create the text file
            string txtOutputPath = tileFilePath + ".txt";

            WriteToFile(output, txtOutputPath);
            //2. save output path for the main file export
            exportedTiles.Add(txtOutputPath);

            //3. Convert the txt to las using LasTools
            //format: x, y, z, class, user comment (id), R, G, B
            string cmd = $"{txt2lasCmd} {txtOutputPath}";

            CCmdController.RunLasToolsCmd(cmd, tileFilePath + ".las");

            CAnalytics.lasExportDuration = CAnalytics.GetDuration(exportStart);
        }
コード例 #3
0
ファイル: CProjectData.cs プロジェクト: ja003/ForestReco2
        public static void Init()
        {
            saveFileName = CUtils.GetFileName(
                CParameterSetter.GetStringSettings(ESettings.forestFileFullName));
            string outputFolderSettings = CParameterSetter.GetStringSettings(ESettings.outputFolderPath);

            //include the method alias into the main folder name
            EDetectionMethod method = CTreeManager.GetDetectMethod();
            string           suffix = CUtils.GetMethodSuffix(method);

            saveFileName += suffix;

            outputFolder = CObjExporter.CreateFolderIn(saveFileName, outputFolderSettings);

            Points = new CPointsHolder();
        }
コード例 #4
0
        public List <Vector3> GetPoints(EClass pClass)
        {
            switch (pClass)
            {
            case EClass.Unassigned:
                //points has been filtered out in fields only
                if (CTreeManager.GetDetectMethod() == EDetectionMethod.Balls)
                {
                    return(ballArray.GetPoints());
                }
                return(unassigned);

            case EClass.Balls:
                return(ballPoints);

            case EClass.BallsMainPoints:
                return(ballsMainPoints);

            case EClass.BallsCenters:
                return(ballsCenters);

            case EClass.BallsSurface:
                return(ballsSurface);

            case EClass.Ground:
                return(ground);

            case EClass.Vege:
                return(vege);

            case EClass.Building:
                return(building);
            }
            CDebug.Error($"Points of class {pClass} not defined");
            return(null);
        }
コード例 #5
0
        private void ProcessUnassignedPoints()
        {
            DateTime debugStart         = DateTime.Now;
            DateTime previousDebugStart = DateTime.Now;

            for (int i = 0; i < unassigned.Count; i++)
            {
                if (CProjectData.backgroundWorker.CancellationPending)
                {
                    return;
                }
                CDebug.Progress(i, unassigned.Count, 100000, ref previousDebugStart, debugStart, "ProcessUnassignedPoints");

                if (CProjectData.backgroundWorker.CancellationPending)
                {
                    return;
                }

                Vector3 point = unassigned[i];
                unassignedArray.AddPointInField(point);
                if (CTreeManager.GetDetectMethod() == EDetectionMethod.Balls)
                {
                    ballArray.AddPointInField(point);
                }
            }

            if (CTreeManager.GetDetectMethod() == EDetectionMethod.Balls)
            {
                //unassignedArray.FillArray(); //doesnt make sense

                const bool filterBasedOnheight = false;
                //balls are expected to be in this height above ground
                if (filterBasedOnheight)
                {
                    ballArray.FilterPointsAtHeight(1.8f, 2.7f);
                }

                //add filtered points to detail array
                List <Vector3> filteredPoints = ballArray.GetPoints();
                foreach (Vector3 point in filteredPoints)
                {
                    if (CProjectData.backgroundWorker.CancellationPending)
                    {
                        return;
                    }

                    ballDetailArray.AddPointInField(point);
                }

                List <CBallField> ballFields = new List <CBallField>();

                //vege.Sort((b, a) => a.Z.CompareTo(b.Z)); //sort descending by height

                List <CBallField> sortedFields = ballDetailArray.fields;
                //sortedFields.Sort((a, b) => a.indexInField.Item1.CompareTo(b.indexInField.Item1));
                //sortedFields.Sort((a, b) => a.indexInField.Item2.CompareTo(b.indexInField.Item2));

                sortedFields.OrderBy(a => a.indexInField.Item1).ThenBy(a => a.indexInField.Item2);

                //List<Vector3> mainPoints = new List<Vector3>();

                debugStart         = DateTime.Now;
                previousDebugStart = DateTime.Now;
                //process
                for (int i = 0; i < sortedFields.Count; i++)
                {
                    if (CProjectData.backgroundWorker.CancellationPending)
                    {
                        return;
                    }
                    CDebug.Progress(i, sortedFields.Count, 100000, ref previousDebugStart, debugStart, "Detecting balls");

                    CBallField field = (CBallField)sortedFields[i];
                    field.Detect();
                    if (field.ball != null && field.ball.isValid)
                    {
                        ballFields.Add(field);
                        ballsMainPoints.AddRange(field.ball.GetMainPoints(true));

                        ballsCenters.Add(field.ball.center);
                        ballsCenters.AddRange(CUtils.GetPointCross(field.ball.center));
                        //return;
                        ballsSurface.AddRange(field.ball.GetSurfacePoints());
                    }
                }

                foreach (CBallField field in ballFields)
                {
                    ballPoints.AddRange(field.points);
                }
            }
        }
コード例 #6
0
ファイル: CProgramStarter.cs プロジェクト: ja003/ForestReco2
        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());
        }
コード例 #7
0
ファイル: CProgramStarter.cs プロジェクト: ja003/ForestReco2
        private static EProcessResult ProcessTile(string pTilePath, int pTileIndex)
        {
            //has to reinit first for the correct progress output
            CDebug.ReInit();

            DateTime startTime = DateTime.Now;

            currentTileIndex = pTileIndex;


            List <Tuple <EClass, Vector3> > parsedLines;

            if (CRxpParser.IsRxp)
            {
                CRxpInfo rxpInfo = CRxpParser.ParseFile(pTilePath);
                parsedLines = rxpInfo.ParsedLines;
                //for now we expect only one tile in rxp processing
                CProjectData.currentTileHeader = rxpInfo.Header;
                CProjectData.mainHeader        = rxpInfo.Header;
            }
            else
            {
                string[] lines   = CProgramLoader.GetFileLines(pTilePath);
                bool     linesOk = lines != null && lines.Length > 0 && !string.IsNullOrEmpty(lines[0]);
                if (linesOk && CHeaderInfo.HasHeader(lines[0]))
                {
                    //todo: where to init header?
                    CProjectData.currentTileHeader = new CHeaderInfo(lines);
                }
                else
                {
                    const string noHeaderMsg = "Processed tile has no header";
                    CDebug.Error(noHeaderMsg);
                    throw new Exception(noHeaderMsg);
                }
                parsedLines = CProgramLoader.ParseLines(lines, true);
            }

            //has to be called after currentTileHeader is assigned
            CProjectData.ReInit(pTileIndex);             //has to reinit after each tile is processed
            CTreeManager.Reinit();

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

            CProgramLoader.ProcessParsedLines(parsedLines);

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

            CTreeManager.DebugTrees();

            CDebug.Step(EProgramStep.Export3D);
            CObjPartition.ExportPartition("", "tile" + pTileIndex);

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

            //has to be called after ExportPartition where final folder location is determined
            try
            {
                CDebug.Step(EProgramStep.Bitmap);
                CBitmapExporter.Export(pTileIndex);
            }
            catch (Exception e)
            {
                CDebug.Error("exception: " + e.Message);
            }

            CAnalytics.totalDuration = CAnalytics.GetDuration(startTime);
            CDebug.Duration("total time", startTime);

            CDebug.Step(EProgramStep.Dart);
            CDartTxt.ExportTile();

            CDebug.Step(EProgramStep.Shp);
            CShpController.ExportCurrent();

            CDebug.Step(EProgramStep.Las);
            CLasExporter.ExportTile();

            CDebug.Step(EProgramStep.Analytics);
            CAnalytics.Write(true);

            return(EProcessResult.Done);
        }
コード例 #8
0
ファイル: CProgramLoader.cs プロジェクト: ja003/ForestReco2
        public static void ProcessParsedLines(List <Tuple <EClass, Vector3> > parsedLines)
        {
            CAnalytics.loadedPoints = parsedLines.Count;
            CProjectData.Points.AddPointsFromLines(parsedLines);

            CObjPartition.AddGroundArrayObj();

            if (CParameterSetter.GetBoolSettings(ESettings.exportPoints))
            {
                CObjPartition.AddPoints(EClass.Unassigned);
                CObjPartition.AddPoints(EClass.Ground);
                CObjPartition.AddPoints(EClass.Vege);
                CObjPartition.AddPoints(EClass.Building);
            }

            CDebug.Count("Trees", CTreeManager.Trees.Count);

            CTreeManager.CheckAllTrees();

            CDebug.Step(EProgramStep.ValidateTrees1);
            //dont move invalid trees to invalid list yet, some invalid trees will be merged
            CTreeManager.ValidateTrees(false, false);

            //export before merge
            if (CProjectData.exportBeforeMerge)
            {
                CTreeManager.AssignMaterials();                 //call before export

                CObjPartition.AddTrees(true);
                CObjPartition.AddTrees(false);
                CObjPartition.ExportPartition("_noMerge");
                CObjPartition.Init();
                //CObjPartition.AddArray();
            }

            CAnalytics.firstDetectedTrees = CTreeManager.Trees.Count;

            CDebug.Step(EProgramStep.MergeNotTrees1);
            CTreeManager.TryMergeNotTrees();


            CDebug.Step(EProgramStep.MergeTrees1);
            //try merge all (even valid)
            EDetectionMethod detectionMethod = CTreeManager.GetDetectMethod();

            if ((detectionMethod == EDetectionMethod.AddFactor ||
                 detectionMethod == EDetectionMethod.Detection2D
                 ) &&
                CProjectData.tryMergeTrees)
            {
                CTreeManager.TryMergeAllTrees(false);
            }
            CAnalytics.afterFirstMergedTrees = CTreeManager.Trees.Count;

            //validate restrictive
            bool cathegorize = false;

            if (detectionMethod == EDetectionMethod.Detection2D)
            {
                cathegorize = true;
            }

            CDebug.Step(EProgramStep.ValidateTrees2);
            CTreeManager.ValidateTrees(cathegorize, true);

            CDebug.Step(EProgramStep.MergeTrees2);
            if (detectionMethod == EDetectionMethod.AddFactor)
            {
                //merge only invalid
                if (CProjectData.tryMergeTrees2)
                {
                    CTreeManager.TryMergeAllTrees(true);
                }
            }

            //try merging not-trees again after trees were merged
            CDebug.Step(EProgramStep.MergeNotTrees2);
            CTreeManager.TryMergeNotTrees();

            CDebug.Step(EProgramStep.ValidateTrees3);
            if (detectionMethod == EDetectionMethod.AddFactor)
            {
                //validate restrictive
                //cathegorize invalid trees
                CTreeManager.ValidateTrees(true, true, true);
            }

            //todo: just debug
            //CTreeManager.CheckAllTrees();

            CAnalytics.detectedTrees        = CTreeManager.Trees.Count;
            CAnalytics.invalidTrees         = CTreeManager.InvalidTrees.Count;
            CAnalytics.invalidTreesAtBorder = CTreeManager.GetInvalidTreesAtBorderCount();

            CAnalytics.inputAverageTreeHeight = CTreeManager.AVERAGE_TREE_HEIGHT;
            CAnalytics.averageTreeHeight      = CTreeManager.GetAverageTreeHeight();
            CAnalytics.maxTreeHeight          = CTreeManager.MaxTreeHeight;
            CAnalytics.minTreeHeight          = CTreeManager.GetMinTreeHeight();

            CDebug.Count("Trees", CTreeManager.Trees.Count);
            CDebug.Count("InvalidTrees", CTreeManager.InvalidTrees.Count);
            //CProjectData.array.DebugDetectedTrees();

            CTreeManager.AssignMaterials();

            CDebug.Step(EProgramStep.AssignReftrees);
            CReftreeManager.AssignRefTrees();
            if (CParameterSetter.GetBoolSettings(ESettings.exportRefTrees))            //no reason to export when no refTrees were assigned
            {
                //CRefTreeManager.ExportTrees();
                CObjPartition.AddRefTrees();
            }

            CObjPartition.AddTrees(true);
            if (CParameterSetter.GetBoolSettings(ESettings.exportInvalidTrees))
            {
                CObjPartition.AddTrees(false);
            }
        }