/// <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); }
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); }
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(); }
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); }
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); } } }
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()); }
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); }
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); } }