Пример #1
0
        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);
        }
Пример #2
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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /*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);
        }
Пример #5
0
        private void AddPointsFromLines(List <Tuple <EClass, Vector3> > pParsedLines)
        {
            DateTime addStartTime = DateTime.Now;

            CDebug.WriteLine("AddPointsFromLines " + pParsedLines.Count);
            int pointsToAddCount = pParsedLines.Count;

            pParsedLines.Sort((a, b) => b.Item2.Z.CompareTo(a.Item2.Z));
            //lines are sorted. first point is peak for sure
            Init(pParsedLines[0].Item2, treeIndex, treePointExtent);

            DateTime lineStartTime = DateTime.Now;

            for (int i = 1; i < Math.Min(pParsedLines.Count, pointsToAddCount); i++)
            {
                Tuple <EClass, Vector3> parsedLine = pParsedLines[i];
                Vector3 point = parsedLine.Item2;

                //all points belong to 1 tree. force add it
                AddPoint(point);

                CDebug.Progress(i, pParsedLines.Count, 100000, ref lineStartTime, addStartTime, "added point:");
            }
            CDebug.Duration("All points added", addStartTime);
        }
Пример #6
0
        public CRefTree(string pFileName, int pTreeIndex, float pTreePointExtent, bool pLoadFromFile)
        {
            treeIndex       = pTreeIndex;
            fileName        = pFileName;
            treePointExtent = pTreePointExtent;
            isValid         = true;

            if (pLoadFromFile)
            {
                string[] lines = GetFileLines(pFileName);
                if (lines.Length == 0)
                {
                    isValid = false;
                    return;
                }

                LoadObj(pFileName);

                List <Tuple <EClass, Vector3> > parsedLines = CProgramLoader.ParseLines(lines, false);
                AddPointsFromLines(parsedLines);
                DateTime processStartTime = DateTime.Now;
                CDebug.WriteLine("Process");
                Process();
                CDebug.Duration("Processed", processStartTime);
            }
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <summary>
        /// Assigns all vege points in preprocess arrays.
        /// Then it calculates the expected average tree height.
        /// </summary>
        private void PreprocessVegePoints()
        {
            const int debugFrequency = 10000;

            DateTime PreprocessVegePointsStart = DateTime.Now;

            CDebug.WriteLine("PreprocessVegePoints", true);

            DateTime preprocessVegePointsStart = DateTime.Now;
            DateTime previousDebugStart        = DateTime.Now;

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

                Vector3 point = vege[i];
                preprocessDetailArray.AddPointInField(point);
                preprocessNormalArray.AddPointInField(point);

                CDebug.Progress(i, vege.Count, debugFrequency, ref previousDebugStart, preprocessVegePointsStart, "preprocessed point");
            }

            //fill missing heigh - will be used in detection process
            //rank 2 - rank 1 (max) extends local maximas -> unwanted effect
            preprocessDetailArray.FillMissingHeights(2);
            preprocessDetailArray.FillMissingHeights(2);

            CDebug.Duration("PreprocessVegePoints", PreprocessVegePointsStart);

            //determine average tree height
            if (CParameterSetter.GetBoolSettings(ESettings.autoAverageTreeHeight))
            {
                //not valid anymore //why not valid??...seems to work fine
                CTreeManager.AVERAGE_TREE_HEIGHT = preprocessNormalArray.GetAverageZ();

                if (float.IsNaN(CTreeManager.AVERAGE_TREE_HEIGHT))
                {
                    CDebug.Error("AVERAGE_TREE_HEIGHT = NaN. using input value");
                    CTreeManager.AVERAGE_TREE_HEIGHT = CParameterSetter.GetIntSettings(ESettings.avgTreeHeigh);
                }
            }
            else
            {
                CTreeManager.AVERAGE_TREE_HEIGHT = CParameterSetter.GetIntSettings(ESettings.avgTreeHeigh);
            }
        }
Пример #9
0
        private static void LoadTrees(List <string> pFileNames)
        {
            DateTime loadTreesStartTime = DateTime.Now;
            DateTime lastDebugTime      = DateTime.Now;

            CDebug.WriteLine("Load reftrees: ");
            foreach (string fileName in pFileNames)
            {
                CDebug.WriteLine(" - " + fileName);
            }

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

                string fileName = pFileNames[i];
                CDebug.Progress(i, pFileNames.Count, 1, ref lastDebugTime, loadTreesStartTime, "load reftree");

                CRefTree deserializedRefTree     = CRefTree.Deserialize(fileName);
                bool     isDeserializedTreeValid = deserializedRefTree != null &&
                                                   deserializedRefTree.IsCurrentVersion();
                CRefTree refTree = isDeserializedTreeValid ?
                                   deserializedRefTree : new CRefTree(fileName, i, TREE_POINT_EXTENT, true);

                refTree.RefTreeTypeName = fileName;                 //GetTypeName(fileName);

                if (!refTree.isValid)
                {
                    //this reftree is not valid. case for reftrees in 'ignore' folder
                    CDebug.Warning($"Skipping reftree {fileName}");
                    continue;
                }
                //material set durring assigning to tree
                //refTree.Obj.UseMtl = CMaterialManager.GetRefTreeMaterial(counter);

                Trees.Add(refTree);
                CDebug.WriteLine($"Loaded tree: {fileName}. height = {refTree.GetTreeHeight()}");
            }
            CAnalytics.loadReftreesDuration = CAnalytics.GetDuration(loadTreesStartTime);
            CDebug.Duration("Load reftrees", loadTreesStartTime);

            CAnalytics.loadedReftrees = Trees.Count;

            DebugReftrees();
        }
Пример #10
0
        protected override void OnProcess()
        {
            string filePath = GetRefTreeFilePath(fileName, fileName + ".reftree");

            CDebug.WriteLine("\nfilePath = " + filePath);

            if (File.Exists(filePath))
            {
                if (!IsCurrentVersion())
                {
                    File.Delete(filePath);
                    CDebug.Warning($"deleting old .reftree file ({filePath})");
                }
                else
                {
                    CDebug.Error(".reftree file already exists ({filePath})");
                }
                //return;
            }

            DateTime processStartTime = DateTime.Now;

            CDebug.WriteLine("Serialization");
            List <string> serializedTree = Serialize();

            version = CURRENT_REFTREE_VERSION;

            using (StreamWriter file = new StreamWriter(filePath, false))
            {
                foreach (string line in serializedTree)
                {
                    file.WriteLine(line);
                }
            }
            CDebug.Duration("Serialized", processStartTime);
            CDebug.WriteLine("saved to: " + filePath);
        }
Пример #11
0
        public static void Export(int pTileIndex)
        {
            if (!exportBitmap)
            {
                return;
            }

            //init for each tile
            treeMarkerSize = GetTreeBrushSize(false);

            DateTime bitmapStart = DateTime.Now;

            CVegeArray array  = CProjectData.Points.vegeDetailArray;
            Bitmap     bitmap = new Bitmap(array.arrayXRange, array.arrayYRange);

            int maxValue = 0;

            for (int x = 0; x < array.arrayXRange; x++)
            {
                for (int y = 0; y < array.arrayYRange; y++)
                {
                    CVegeField element  = array.GetField(x, y);
                    int?       colorVal = element.GetColorValue();               //from detailed array

                    if (colorVal == null)
                    {
                        continue;
                    }

                    int colorVaInt = (int)colorVal;
                    if (colorVaInt > maxValue)
                    {
                        maxValue = colorVaInt;
                    }

                    int rVal = colorVaInt;
                    //highlight buffer zone
                    bool isAtBufferZone = CTreeMath.IsAtBufferZone(element.Center);
                    if (isAtBufferZone)
                    {
                        rVal = Math.Min(rVal + 30, 255);
                    }

                    Color color = Color.FromArgb(rVal, colorVaInt, colorVaInt);
                    //CDebug.WriteLine($"{x},{y} = {color}");

                    bitmap.SetPixel(x, y, color);


                    if (exportMain && !isAtBufferZone)
                    {
                        Tuple <int, int> posInMain = GetIndexInMainBitmap(element.Center);

                        if (posInMain == null)
                        {
                            continue;
                        }

                        if (color.R > 255)
                        {
                            CDebug.Error("color.R = " + color.R);
                        }
                        mainMap.SetPixel(posInMain.Item1, posInMain.Item2, color);
                    }
                }
            }

            //StretchColorRange(ref bitmap, maxValue);

            //FilterBitmap(ref bitmap, GetKernelSize(array.stepSize, .2f), EFilter.Max);

            if (exportHeightmap)
            {
                ExportBitmap(bitmap, "heightmap", pTileIndex);
            }

            int  bitmapsCount = 3;
            bool useCheckTree = CParameterSetter.GetBoolSettings(ESettings.useCheckTreeFile);

            if (useCheckTree)
            {
                bitmapsCount++;
            }

            CDebug.Progress(1, bitmapsCount, 1, ref bitmapStart, bitmapStart, "bitmap: ");

            if (exportPositions)
            {
                Bitmap bitmapTreePos = new Bitmap(bitmap);
                AddTreesToBitmap(array, bitmapTreePos, true, false);
                ExportBitmap(bitmapTreePos, "tree_positions", pTileIndex);

                if (useCheckTree)
                {
                    Bitmap bitmapChecktree = new Bitmap(bitmapTreePos);
                    ExportBitmap(bitmapChecktree, "tree_check", pTileIndex);
                    CDebug.Progress(bitmapsCount - 1, bitmapsCount, 1, ref bitmapStart, bitmapStart, "bitmap: ");
                }
            }

            CDebug.Progress(2, bitmapsCount, 1, ref bitmapStart, bitmapStart, "bitmap: ");

            if (exportBorders)
            {
                Bitmap bitmapTreeBorder = new Bitmap(bitmap);
                AddTreesToBitmap(array, bitmapTreeBorder, true, true);
                ExportBitmap(bitmapTreeBorder, "tree_borders", pTileIndex);
            }

            CDebug.Progress(bitmapsCount, bitmapsCount, 1, ref bitmapStart, bitmapStart, "bitmap: ");

            CAnalytics.bitmapExportDuration = CAnalytics.GetDuration(bitmapStart);
            CDebug.Duration("bitmap export", bitmapStart);
        }
Пример #12
0
        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);
        }
Пример #13
0
        /// <summary>
        /// Assigns to each of detected trees the most suitable refTree
        /// </summary>
        public static void AssignRefTrees()
        {
            if (Trees.Count == 0)
            {
                //CDebug.Error("no reftrees loaded");
                return;
            }

            DateTime addTreeObjModelsStart = DateTime.Now;

            CDebug.WriteLine("Get reftree models");

            const int debugFrequency = 10;

            DateTime assignRefTreesStart = DateTime.Now;

            CDebug.WriteLine("AssignRefTrees");

            DateTime previousDebugStart = DateTime.Now;

            int   counter       = 0;
            float similaritySum = 0;

            foreach (CTree t in CTreeManager.Trees)
            {
                if (CProjectData.backgroundWorker.CancellationPending)
                {
                    break;
                }

                Tuple <CRefTree, STreeSimilarity> suitableRefTree = GetMostSuitableRefTree(t);
                CRefTree mostSuitableRefTree = suitableRefTree.Item1;
                if (mostSuitableRefTree == null)
                {
                    CDebug.Error("no reftrees assigned!");
                    continue;
                }

                SetRefTreeObjTransform(ref mostSuitableRefTree, t, suitableRefTree.Item2.angleOffset);
                similaritySum += suitableRefTree.Item2.similarity;
                //CDebug.WriteLine($"similaritySum += {suitableRefTree.Item2.similarity}");

                Obj suitableTreeObj = mostSuitableRefTree.Obj.Clone();
                suitableTreeObj.Name += "_" + t.treeIndex;
                t.assignedRefTreeObj  = suitableTreeObj;
                t.assignedRefTree     = mostSuitableRefTree;
                //t.RefTreeTypeName = mostSuitableRefTree.RefTreeTypeName; //copy the type name

                suitableTreeObj.UseMtl = t.assignedMaterial.Name;

                CDebug.Progress(counter, CTreeManager.Trees.Count, debugFrequency, ref previousDebugStart, assignRefTreesStart, "Assigned reftree");
                counter++;


                //CDebug.WriteLine("\n mostSuitableRefTree = " + mostSuitableRefTree);
            }


            CAnalytics.averageReftreeSimilarity = similaritySum / CTreeManager.Trees.Count;

            CAnalytics.reftreeAssignDuration = CAnalytics.GetDuration(addTreeObjModelsStart);
            CDebug.Duration("Assign reftree models", addTreeObjModelsStart);
        }