/// <summary> /// Classify each point into its according points list. /// Then adds it to its array. /// </summary> public void AddPointsFromLines(List <Tuple <EClass, Vector3> > pParsedLines) { ClassifyPoints(pParsedLines); DateTime processStartTime = DateTime.Now; CDebug.Count("ProcessParsedLines", pParsedLines.Count); //TODO: unite processing all points CDebug.Step(EProgramStep.ProcessUnassignedPoints); ProcessUnassignedPoints(); CDebug.Step(EProgramStep.ProcessBuildingPoints); ProcessBuildingPoints(); CDebug.Step(EProgramStep.ProcessGroundPoints); ProcessGroundPoints(); CDebug.Step(EProgramStep.PreprocessVegePoints); PreprocessVegePoints(); CDebug.Step(EProgramStep.ProcessVegePoints); ProcessVegePoints(); SetAnalytics(); CDebug.Duration("All points added", processStartTime); }
/// <summary> /// just check /// </summary> public void DebugDetectedTrees() { int detectedTreesCount = 0; int validTreesCount = 0; int invalidTreesCount = 0; foreach (CTreeField f in fields) { detectedTreesCount += f.DetectedTrees.Count; if (f.DetectedTrees.Count != 0) { foreach (CTree tree in f.DetectedTrees) { if (tree.isValid) { validTreesCount++; } else { invalidTreesCount++; } } } } CDebug.Count("Detected trees", detectedTreesCount); CDebug.Count("valid trees", validTreesCount); CDebug.Count("invalid trees", invalidTreesCount); }
public static void TryMergeAllTrees(bool pOnlyInvalid) { IsMerging = true; DateTime mergeStartTime = DateTime.Now; CDebug.WriteLine("TryMergeAllTrees"); Trees.Sort((a, b) => b.peak.Center.Z.CompareTo(a.peak.Center.Z)); int treeCountBeforeMerge = Trees.Count; if (detectMethod == EDetectionMethod.AddFactor) { MergeGoodAddFactorTrees(pOnlyInvalid); } if (detectMethod == EDetectionMethod.Detection2D) { Merge2DTrees(); } if (pOnlyInvalid) { CAnalytics.secondMergeDuration = CAnalytics.GetDuration(mergeStartTime); } else { CAnalytics.firstMergeDuration = CAnalytics.GetDuration(mergeStartTime); } IsMerging = false; CDebug.Duration("Trees merge", mergeStartTime); CDebug.Count("Number of trees merged", treeCountBeforeMerge - Trees.Count); }
/*public void AddPointInField(Vector3 pPoint, EPointType pType, bool pLogErrorInAnalytics) * { * Tuple<int, int> index = GetPositionInArray(pPoint); * if (!IsWithinBounds(index)) * { * CDebug.Error($"point {pPoint} is OOB {index}", pLogErrorInAnalytics); * return; * } * switch (pType) * { * case EPointType.Ground: * array[index.Item1, index.Item2].AddGroundPoint(pPoint); * break; * case EPointType.Vege: * array[index.Item1, index.Item2].AddVegePoint(pPoint); * break; * case EPointType.Preprocess: * array[index.Item1, index.Item2].AddPreProcessVegePoint(pPoint); * break; * } * }*/ //public void SortPoints() //{ // foreach (CField field in fields) // { // field.SortPoints(); // } //} /// <summary> /// Approximates the height in undefined fields of ground array. /// </summary> public void FillArray() { CDebug.WriteLine("FillArray", true); DateTime fillAllHeightsStart = DateTime.Now; int counter = 1; while (!IsAllDefined()) { if (CProjectData.backgroundWorker.CancellationPending) { return; } DateTime fillHeightsStart = DateTime.Now; CDebug.Count("FillMissingHeights", counter); FillMissingHeights(counter); counter++; const int maxFillArrayIterations = 5; if (counter > maxFillArrayIterations + 1) { CDebug.Error("FillMissingHeights"); CDebug.Count("too many iterations", counter); break; } CDebug.Duration("FillMissingHeights", fillHeightsStart); } CAnalytics.fillAllHeightsDuration = CAnalytics.GetDuration(fillAllHeightsStart); CDebug.Duration("fillAllHeights", fillAllHeightsStart); }
/// <summary> /// If not-tree is very close to some tree then it is probably part of that tree. /// Not-tree will be merged into the closest one. /// </summary> public static void TryMergeNotTrees() { IsMerging = true; DateTime mergeStartTime = DateTime.Now; CDebug.WriteLine("TryMergeNotTrees"); //sort in descending order - trees will be processed from the end NotTrees.Sort((b, a) => b.peak.Center.Z.CompareTo(a.peak.Center.Z)); //TODO: CHECK!!! THIS IS NOT DESCENDING ORDER??? int treeCountBeforeMerge = NotTrees.Count; for (int i = NotTrees.Count - 1; i >= 0; i--) { CTree notTree = NotTrees[i]; //if(notTree.Equals(335)) // CDebug.WriteLine(""); //just debug //List<CTree> closeTrees2 = CProjectData.Points.treeNormalArray. // GetTreesInMaxStepsFrom(notTree.peak.Center, 1); List <CTree> closeTrees = new List <CTree>(); //fisrt try to get a tree on the same detail field CTree t = CProjectData.Points.treeDetailArray. GetFieldContainingPoint(notTree.peak.Center).GetSingleDetectedTree(); if (t != null) { closeTrees.Add(t); } //if no tree is on the same field get some in close distance if (closeTrees.Count == 0) { closeTrees = CProjectData.Points.treeDetailArray. GetTreesInMaxStepsFrom(notTree.peak.Center, 2); } //merge not-tree with the closest tree but only if it is higher. //if not then it is probably some noise above the regular tree if (closeTrees.Count > 0 && closeTrees[0].GetTreeHeight() > notTree.GetTreeHeight() && !notTree.IsLocalMaximum()) { closeTrees[0].MergeWith(notTree); NotTrees.RemoveAt(i); } } IsMerging = false; CDebug.Duration("Not-trees merge", mergeStartTime); CDebug.Count("Number of not-trees merged", treeCountBeforeMerge - Trees.Count); }
/// <summary> /// Reads parsed lines and loads class and point list. /// Result is sorted in descending order. /// </summary> public static List <Tuple <EClass, Vector3> > ParseLines(string[] lines, bool pUseHeader) { CDebug.Step(EProgramStep.ParseLines); //store coordinates to corresponding data strucures based on their class const int DEFAULT_START_LINE = 19; int startLine = pUseHeader && CProjectData.mainHeader != null ? DEFAULT_START_LINE : 0; CDebug.Warning("loading " + lines.Length + " lines!"); int linesToRead = lines.Length; //todo: check that "classic" processed files work correctly without using default class //bool classesCorect = true; List <Tuple <EClass, Vector3> > parsedLines = new List <Tuple <EClass, Vector3> >(); if (useDebugData) { parsedLines = CDebugData.GetStandartTree(); //CDebugData.DefineArray(true, 0); } else { for (int i = startLine; i < linesToRead; i++) { // <class, coordinate> Tuple <EClass, Vector3> c = CLazTxtParser.ParseLine(lines[i], pUseHeader); if (c == null) { continue; } //some files have different class counting. we are interested only in classes in EClass //if(c.Item1 == EClass.Other) //{ // c = new Tuple<EClass, Vector3>(EClass.Vege, c.Item2); // classesCorect = false; //} parsedLines.Add(c); } } //if(!classesCorect) //{ // CDebug.WriteLine("classes not correct. using default class"); //} CDebug.Count("parsedLines", parsedLines.Count); return(parsedLines); }
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); } }