Exemplo n.º 1
0
        //-----------------------------------------------------------------------------

        /// <summary>
        /// Calculates the size of the canvas and determine the number of required tiles.
        /// It then creates polygons (rectangle) for each area considering the given offset.
        /// </summary>
        /// <param name="prmFiles">List of LAS files to be processed</param>
        private void UpdateCommonHeader(IEnumerable <String> prmFiles)
        {
            m_AreaHeader = GetDefaultLasHeader();

            foreach (String lasFile in prmFiles)
            {
                using (TcLasReader lasReader = new TcLasReader(lasFile))
                {
                    m_AreaHeader.MinX = Math.Min(m_AreaHeader.MinX, lasReader.Header.MinX);
                    m_AreaHeader.MinY = Math.Min(m_AreaHeader.MinY, lasReader.Header.MinY);
                    m_AreaHeader.MinZ = Math.Min(m_AreaHeader.MinZ, lasReader.Header.MinZ);
                    m_AreaHeader.MaxX = Math.Max(m_AreaHeader.MaxX, lasReader.Header.MaxX);
                    m_AreaHeader.MaxY = Math.Max(m_AreaHeader.MaxY, lasReader.Header.MaxY);
                    m_AreaHeader.MaxZ = Math.Max(m_AreaHeader.MaxZ, lasReader.Header.MaxZ);

                    m_AreaHeader.XOffset = Math.Min(m_AreaHeader.XOffset, lasReader.Header.XOffset);
                    m_AreaHeader.YOffset = Math.Min(m_AreaHeader.YOffset, lasReader.Header.YOffset);
                    m_AreaHeader.ZOffset = Math.Min(m_AreaHeader.ZOffset, lasReader.Header.ZOffset);

                    m_AreaHeader.XScaleFactor = Math.Min(m_AreaHeader.XScaleFactor, lasReader.Header.XScaleFactor);
                    m_AreaHeader.YScaleFactor = Math.Min(m_AreaHeader.YScaleFactor, lasReader.Header.YScaleFactor);
                    m_AreaHeader.ZScaleFactor = Math.Min(m_AreaHeader.ZScaleFactor, lasReader.Header.ZScaleFactor);

                    m_TileInfos[lasFile] = new TcIndexedLasInfo(lasFile)
                    {
                        Header = lasReader.Header
                    };
                }
            }
        }
Exemplo n.º 2
0
        //-----------------------------------------------------------------------------

        public LasPoint2[] GetPointsByTile(String prmInput, Int32 prmRow, Int32 prmCol)
        {
            String blockFile = String.Format(@"{0}\{1}.xml", Path.GetDirectoryName(prmInput), Path.GetFileNameWithoutExtension(prmInput));
            TcTileBlockInfoCollection tileInfoCollection = TcTileUtils.GetTileBlocks(blockFile);

            IEnumerable <TcTileBlockInfo> blocks = tileInfoCollection.TileBlocks.Where(iter => iter.Row == prmRow && iter.Col == prmCol);
            Int32 numberOfPoints = blocks.Aggregate(0, (result, iter) => result += iter.NoOfPoints);

            using (TcLasReader reader = new TcLasReader(prmInput))
            {
                LasHeader   header     = reader.GetHeaderOld();
                LasPoint2[] points     = new LasPoint2[numberOfPoints];
                Int32       arrayStart = 0;
                foreach (TcTileBlockInfo info in blocks)
                {
                    if (reader.GetLasBlock(ref points, arrayStart, info.StartPoint, info.NoOfPoints, header))
                    {
                        arrayStart += info.NoOfPoints;
                    }
                    else
                    {
                        throw new Exception(String.Format("Couldn't read the las tile ({0},{1})", prmRow, prmCol));
                    }
                }
                return(points);
            }
        }
Exemplo n.º 3
0
        //-----------------------------------------------------------------------------

        public void Index(String prmInput, String prmOutput)
        {
            if (!File.Exists(prmInput))
            {
                throw new FileNotFoundException("LAS file not found");
            }

            using (TcLasReader reader = new TcLasReader(prmInput))
            {
                switch (reader.Header.PointDataFormatID)
                {
                case 0:
                    ProcessTiles <TsLasPoint0>(reader, prmOutput);
                    break;

                case 1:
                    ProcessTiles <TsLasPoint1>(reader, prmOutput);
                    break;

                case 2:
                    ProcessTiles <TsLasPoint2>(reader, prmOutput);
                    break;

                case 3:
                    ProcessTiles <TsLasPoint3>(reader, prmOutput);
                    break;

                case 4:
                    ProcessTiles <TsLasPoint4>(reader, prmOutput);
                    break;

                case 5:
                    ProcessTiles <TsLasPoint5>(reader, prmOutput);
                    break;

                case 6:
                    ProcessTiles <TsLasPoint6>(reader, prmOutput);
                    break;

                case 7:
                    ProcessTiles <TsLasPoint7>(reader, prmOutput);
                    break;

                case 8:
                    ProcessTiles <TsLasPoint8>(reader, prmOutput);
                    break;

                case 9:
                    ProcessTiles <TsLasPoint9>(reader, prmOutput);
                    break;

                case 10:
                    ProcessTiles <TsLasPoint10>(reader, prmOutput);
                    break;

                default:
                    throw new FormatException("Couldn't process the tile. LAS format not supported");
                }
            }
        }
Exemplo n.º 4
0
        //-----------------------------------------------------------------------------

        public void LasToCls(String prmInput, Int64 prmOriginalNumberOfPoints, String prmOutputAcl, String prmOutputAcb)
        {
            try
            {
                // Process the LAS file.
                using (TcLasReader reader = new TcLasReader(prmInput))
                {
                    switch (reader.Header.PointDataFormatID)
                    {
                    case 1:
                        LasToCls <TsLasPoint1>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    case 3:
                        LasToCls <TsLasPoint3>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    case 4:
                        LasToCls <TsLasPoint4>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    case 5:
                        LasToCls <TsLasPoint5>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    case 6:
                        LasToCls <TsLasPoint6>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    case 7:
                        LasToCls <TsLasPoint7>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    case 8:
                        LasToCls <TsLasPoint8>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    case 9:
                        LasToCls <TsLasPoint9>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    case 10:
                        LasToCls <TsLasPoint10>(reader, prmOriginalNumberOfPoints, prmOutputAcl, prmOutputAcb);
                        break;

                    default:
                        throw new FormatException("Couldn't produce the file. LAS format not supported");
                    }
                }
            }
            catch (Exception ex)
            {
                ReportError("Could not construct Acl and Acb files from LAS", ex);
            }
        }
Exemplo n.º 5
0
        //-----------------------------------------------------------------------------

        public void ClsToLas(String prmOriginalLasFile, String prmAclFile, String prmAcbFile, String prmOutputLas)
        {
            try
            {
                using (TcLasReader lasReader = new TcLasReader(prmOriginalLasFile))
                {
                    switch (lasReader.Header.PointDataFormatID)
                    {
                    case 1:
                        ClsToLas <TsLasPoint1>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    case 3:
                        ClsToLas <TsLasPoint3>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    case 4:
                        ClsToLas <TsLasPoint4>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    case 5:
                        ClsToLas <TsLasPoint5>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    case 6:
                        ClsToLas <TsLasPoint6>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    case 7:
                        ClsToLas <TsLasPoint7>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    case 8:
                        ClsToLas <TsLasPoint8>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    case 9:
                        ClsToLas <TsLasPoint9>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    case 10:
                        ClsToLas <TsLasPoint10>(lasReader, prmAclFile, prmAcbFile, prmOutputLas);
                        break;

                    default:
                        throw new FormatException("Couldn't produce the file. LAS format not supported");
                    }
                }
            }
            catch (Exception ex)
            {
                ReportError("Could not reconstruct LAS from Acb and Acl files", ex);
            }
        }
Exemplo n.º 6
0
        //-----------------------------------------------------------------------------

        #region LasToCls - Converter function from LAS to Classification format

        private void LasToCls <T>(TcLasReader prmReader, String prmOutput) where T : TiLasPoint
        {
            m_Progress = 0;

            ReportMessage(String.Format("Processing {0}", Path.GetFileName(prmOutput)));
            using (TcClsWriter writer = new TcClsWriter(prmReader.Header, prmOutput))
            {
                writer.WriteHeader(prmReader.OffsetBytes);

                Int64 numberOfPointRecords = prmReader.Header.GetNumberOfPoints();
                Int64 noOfPointsLoaded     = 0;
                Int64 noOfPointsToRead     = 0;

                while (noOfPointsLoaded < numberOfPointRecords)
                {
                    noOfPointsToRead = Math.Min(TcConstants.MaxLasPointsToProcessAtOnce, numberOfPointRecords - noOfPointsLoaded);
                    writer.WritePoints <T>(prmReader.ReadPoints <T>(noOfPointsToRead));
                    noOfPointsLoaded += noOfPointsToRead;
                    ReportProgress(noOfPointsLoaded, numberOfPointRecords);
                }
            }
            ReportMessage(String.Format("Finished {0}", Path.GetFileName(prmOutput)));
        }
Exemplo n.º 7
0
        //-----------------------------------------------------------------------------

        private void ClsToLas <T>(TcLasReader prmReader, String prmAclFile, String prmAcbFile, String prmOutputLas) where T : TiLasGPS
        {
            using (BinaryReader acbReader = new BinaryReader(new FileStream(prmAcbFile, FileMode.Open)))
            {
                Int64 totalPoints = acbReader.ReadInt64();

                // When the binary file doesn't have enough points.
                if (totalPoints != (acbReader.BaseStream.Length - acbReader.BaseStream.Position))
                {
                    throw new InvalidDataException(String.Format("Length of data mismatched in {0} file", Path.GetFileName(prmAcbFile)));
                }

                // Check against the number of points in the original LAS files.
                if (totalPoints != prmReader.TotalPoints)
                {
                    throw new InvalidDataException(String.Format("{0} file doesn't have save number of points as LAS", Path.GetFileName(prmAcbFile)));
                }

                using (TcLasWriter lasWriter = new TcLasWriter(prmOutputLas))
                {
                    Int64  noOfPointsToProcess = 0;
                    Int64  noOfPointsProcessed = 0;
                    T[]    points  = new T[TcConstants.MaxLasPointsToProcessAtOnce];
                    Byte[] clsData = acbReader.ReadBytes((Int32)totalPoints);

                    // Write the header.
                    lasWriter.WriteHeader(prmReader.Header, prmReader.OffsetBytes);

                    while (noOfPointsProcessed < prmReader.TotalPoints)
                    {
                        // Calculate how many points to read.
                        noOfPointsToProcess = Math.Min(TcConstants.MaxLasPointsToProcessAtOnce, prmReader.TotalPoints - noOfPointsProcessed);

                        // Read a block of points from the LAS file.
                        points = prmReader.ReadPoints <T>(noOfPointsToProcess);

                        // Update the classification flag.
                        for (int i = 0; i < noOfPointsToProcess; i++)
                        {
                            points[i].Classification = clsData[noOfPointsProcessed + i];
                        }

                        lasWriter.WritePoints <T>(points);

                        // Notify the progress to the caller thread.
                        ReportProgress(noOfPointsProcessed, totalPoints);

                        noOfPointsProcessed += noOfPointsToProcess;
                    }

                    // Process the extra points if there is any.
                    if (!String.IsNullOrWhiteSpace(prmAclFile) && File.Exists(prmAclFile))
                    {
                        using (TcClsReader clsReader = new TcClsReader(prmAclFile))
                        {
                            TsClsLasPoint[] extraPoints    = clsReader.ReadPoints(clsReader.TotalPoints);
                            TiLasGPS[]      extraLasPoints = new TiLasGPS[clsReader.TotalPoints];

                            for (int i = 0; i < clsReader.TotalPoints; i++)
                            {
                                extraLasPoints[i] = ClsToLasPoint(extraPoints[i], clsReader.Header.PointDataFormatID);

                                // Point transformation as the offset and/or scaling factor might be changed in different software.
                                extraLasPoints[i].X = (Int32)(((clsReader.Header.XOffset + extraLasPoints[i].X * clsReader.Header.XScaleFactor) - prmReader.Header.XOffset) / prmReader.Header.XScaleFactor);
                                extraLasPoints[i].Y = (Int32)(((clsReader.Header.YOffset + extraLasPoints[i].Y * clsReader.Header.YScaleFactor) - prmReader.Header.YOffset) / prmReader.Header.YScaleFactor);
                                extraLasPoints[i].Z = (Int32)(((clsReader.Header.ZOffset + extraLasPoints[i].Z * clsReader.Header.ZScaleFactor) - prmReader.Header.ZOffset) / prmReader.Header.ZScaleFactor);
                            }
                            lasWriter.WritePoints(extraLasPoints);

                            // Write the updated header.
                            lasWriter.WriteHeader(GetHeaderForMergedLas(prmReader.Header, clsReader.TotalPoints));
                        }
                    }
                }
            }
        }
Exemplo n.º 8
0
        //-----------------------------------------------------------------------------

        private void LasToCls <T>(TcLasReader prmReader, Int64 prmOriginalNumberOfPoints, String prmOutputAcl, String prmOutputAcb) where T : TiLasGPS
        {
            ReportMessage(String.Format("Processing {0}", Path.GetFileName(prmOutputAcb)));
            ReportMessage("Reading all LAS points");

            // Read all the points.
            T[] clsPoints = prmReader.ReadPoints <T>(prmReader.TotalPoints);

            ReportMessage("Sorting LAS points according to the GPS time");

            // Sort the points according to the GPS time.
            new TcLasSort <T>().SortByGpsTime(clsPoints, 0, prmReader.TotalPoints - 1);

            Int64 pointsProcessed = 0;

            Byte[] clsData = new Byte[prmOriginalNumberOfPoints];

            ReportMessage("Extracting the new points");

            // Count the number of points with GPSTime ~ 0 (new point)
            Int32 exptCnt = 0;

            while (clsPoints[exptCnt].GPSTime < 1)
            {
                exptCnt++;
            }

            // Write the new points in .acl file.
            if (exptCnt > 0)
            {
                using (TcClsWriter clsWriter = new TcClsWriter(GetHeaderForCls(prmReader.Header, exptCnt), prmOutputAcl))
                {
                    clsWriter.WriteHeader(prmReader.OffsetBytes);
                    clsWriter.WritePoints <T>(clsPoints.Take(exptCnt).ToArray());
                }
            }
            pointsProcessed += exptCnt;

            // Counter for the original points.
            Int64 origPtCnt = 0;

            // Current expected GPS time to map the deleted points.
            Double expecteGPSTime = 1.0;

            ReportMessage("Processing original points");

            while (pointsProcessed < clsPoints.Length && origPtCnt < prmOriginalNumberOfPoints)
            {
                // If deleted points have been detected.
                if (clsPoints[pointsProcessed].GPSTime != expecteGPSTime)
                {
                    clsData[origPtCnt++] = 255;
                    expecteGPSTime++;
                    continue;
                }

                clsData[origPtCnt++] = clsPoints[pointsProcessed++].Classification;
                expecteGPSTime++;
            }

            ReportMessage("Writing the output classification files");

            // Write into the stream.
            if (origPtCnt > 0)
            {
                using (BinaryWriter acbWriter = new BinaryWriter(new FileStream(prmOutputAcb, FileMode.Create)))
                {
                    acbWriter.Write(origPtCnt);
                    acbWriter.Write(clsData);
                }
            }
            ReportMessage(String.Format("Finished {0}", Path.GetFileName(prmOutputAcb)));
        }
Exemplo n.º 9
0
        //-----------------------------------------------------------------------------

        public void Tile(String prmInput, String prmOutput)
        {
            // Variables to be used inside the big loop.
            LasPoint2 point;
            // Int32 east, north, col, row;
            Int32 tileOffset      = 0;
            Int32 index           = -1;
            Int32 pointsProcessed = 0;

            using (TcLasReader reader = new TcLasReader(prmInput))
            {
                LasHeader header = reader.GetHeaderOld();
                UpdateTileCounts(header, m_TileSize);

                String blockFile = String.Format(@"{0}\{1}.xml", Path.GetDirectoryName(prmOutput), Path.GetFileNameWithoutExtension(prmOutput));
                if (File.Exists(blockFile))
                {
                    File.Delete(blockFile);
                }

                using (TcLasWriter writer = new TcLasWriter(prmOutput))
                {
                    header.MinX = m_RevisedEast;
                    header.MaxY = m_RevisedNorth;

                    writer.WriteHeader(header);
                    Int32 onePercent = header.NumberOfPointRecords / 100;

                    for (int i = 0; i < header.NumberOfPointRecords; i++)
                    {
                        point = reader.ReadPoint(header);
                        if (point.X <= 0 || point.Y <= 0)
                        {
                            continue;
                        }

                        // Calculate the tile index for the point.
                        tileOffset = m_TileSize * m_Factor;

/*
 *                      east = Convert.ToInt32(point.X - (point.X % tileOffset));
 *                      north = Convert.ToInt32(point.Y - (point.Y % tileOffset)) + tileOffset;
 *                      col = (east - m_RevisedEast) / tileOffset;
 *                      row = (m_RevisedNorth - north) / tileOffset;
 */
                        Int32[] rowCol = TcMathUtil.GetRowCol(point.X, point.Y, m_RevisedEast, m_RevisedNorth, tileOffset, tileOffset);
                        index = rowCol[1] * m_TileRows + rowCol[0];

                        // Add that into the intermediate tile block.
                        if (!m_TileBlocks.ContainsKey(index))
                        {
                            m_TileBlocks[index]      = new LasPoint2[m_TileBlockSize];
                            m_BlockPointCount[index] = 0;
                        }

                        m_TileBlocks[index][m_BlockPointCount[index]] = point;
                        m_BlockPointCount[index]++;

                        // When a tile block is full, write into file and remove the points.
                        if (m_BlockPointCount[index] == m_TileBlockSize)
                        {
                            writer.WritePoints(m_TileBlocks[index], header, m_TileBlockSize);
                            ProcessTileBlock(rowCol[0], rowCol[1], index, pointsProcessed);
                            pointsProcessed += m_TileBlockSize;
                        }

                        if (i % onePercent == 0)
                        {
                            NotifyTileProgress(prmInput, prmOutput, rowCol[0], rowCol[1], pointsProcessed, i / onePercent);
                        }
                    }

                    // Process the remaining blocks with incomplete size.
                    int row, col;
                    foreach (Int32 idx in m_TileBlocks.Keys.ToList())
                    {
                        row = idx % m_TileRows;
                        col = (idx - row) / m_TileRows;

                        writer.WritePoints(m_TileBlocks[idx], header, m_BlockPointCount[idx]);
                        ProcessTileBlock(row, col, idx, pointsProcessed);
                        pointsProcessed += m_BlockPointCount[idx];
                    }

                    TcTileUtils.SaveTileBlocks(m_TileBlockInfoCollection, blockFile);
                }
            }
        }
Exemplo n.º 10
0
        static void Main(string[] args)
        {
            options = new Options();

            if (CommandLine.Parser.Default.ParseArguments(args, options))
            {
                factor = options.Factor;
                TS     = options.GridSize;

                var    fs    = Stopwatch.StartNew();
                string input = options.InputFile;

                if (string.IsNullOrEmpty(options.OutputFile))
                {
                    if (options.OutputDir != string.Empty)
                    {
                        options.OutputFile = new FileInfo(options.InputFile).Directory.FullName;
                        options.OutputFile = Path.Combine(options.OutputDir, Path.GetFileNameWithoutExtension(options.InputFile) + ".xyz");
                        options.LogFile    = Path.Combine(options.OutputDir, Path.GetFileNameWithoutExtension(options.InputFile) + ".txt");
                    }
                }


                if (!new FileInfo(options.OutputFile).Directory.Exists)
                {
                    new FileInfo(options.OutputFile).Directory.Create();
                }



                #region Title ASCII
                Console.ForegroundColor = ConsoleColor.Green;
                RConsole.Write(@"


                     db    88888 8       db    .d88b. .d88b. 
                    dPYb     8   8      dPYb   YPwww. YPwww. 
                   dPwwYb    8   8     dPwwYb      d8     d8 
                  dP    Yb   8   8888 dP    Yb `Y88P' `Y88P' 
                                                             
                      888b. 8888 888b. .d88b. 888b. 88888 
                      8  .8 8www 8  .8 8P  Y8 8  .8   8   
                      8wwK' 8    8wwP' 8b  d8 8wwK'   8   
                      8  Yb 8888 8     `Y88P' 8  Yb   8   
                                                          
                  888b. 8       db    8b  8 8b  8 8888 888b. 
                  8  .8 8      dPYb   8Ybm8 8Ybm8 8www 8  .8 
                  8wwP' 8     dPwwYb  8   8 8   8    8wwK 
                  8     8888 dP    Yb 8   8 8   8 8888 8  Yb 
                                                             
            ");
                Console.ForegroundColor = ConsoleColor.White;
                #endregion

                #region ASCII Parameter Table
                Console.ForegroundColor = ConsoleColor.Magenta;
                RConsole.WriteLine("               Version: Test Build 0.0.1");
                Console.ForegroundColor = ConsoleColor.White;
                RConsole.WriteLine("                    ---------------------------------------                    ");
                RConsole.WriteLine("");
                RConsole.Write(@"
.......................
: Parameter :   Value :
:...........:.........:
: Scale     :    {0:00}   :
: Grid Size :    {1:00}   :
:...........:.........:
", factor, TS);


                RConsole.WriteLine("");

                #endregion

                #region ASCII I/O Table
                RConsole.WriteLine(@"
+--------+---------------------------------------------------------------------+
| Param  |  Values                                                             |
+--------+---------------------------------------------------------------------+
| Input  | {0, -43}                         |
| Output | {1, -43}                         |
| Log    | {2, -43}                         |
+--------+---------------------------------------------------------------------+
", Path.GetFileName(options.InputFile), options.OutputFile,
                                   Path.GetFileName(options.LogFile));
                #endregion

                if (!File.Exists(input))
                {
                    RConsole.WriteLine("IO Error: input {0} file does not exist.", input);
                    return;
                }

                RConsole.WriteLine("Job Started {0} - {1}", Path.GetFileNameWithoutExtension(input), DateTime.Now.ToString());

                try
                {
                    #region LAS READER / PRE GRID
                    using (var readerobj = new TcLasReader(input))
                    {
                        var s = Stopwatch.StartNew();
                        RConsole.WriteLine("Reading {0} Points", readerobj.TotalPoints);

                        var points = readerobj.ReadPoints(readerobj.TotalPoints, readerobj.Header);
                        s.Stop();
                        RConsole.WriteLine("Reading {0} Points - Finished {1} secs", readerobj.TotalPoints, Math.Ceiling((double)s.ElapsedMilliseconds / 1000));

                        var set = points.GetEnumerator();

                        #region gridding
                        s = Stopwatch.StartNew();

                        var minX = readerobj.Header.MinX;
                        var minY = readerobj.Header.MinY;
                        var maxX = readerobj.Header.MaxX;
                        var maxY = readerobj.Header.MaxY;

                        int X0 = (int)(minX - (minX % (TS * factor)));
                        int Y0 = (int)(minY - (minY % (TS * factor)));
                        int X1 = (int)(maxX - (maxX % (TS * factor)));
                        int Y1 = (int)(maxY - (maxY % (TS * factor)));

                        double dX = X1 - X0;
                        double dY = Y1 - Y0;

                        dX /= TS * factor;
                        dY /= TS * factor;

                        var tiles_x = (int)dX;
                        var tiles_y = (int)dY;

                        preMem  = GC.GetTotalMemory(true);
                        Tiles   = new Tile[tiles_x, tiles_y];
                        postMem = GC.GetTotalMemory(true);
                        calMem  = ToReadableMemUnit((int)Math.Ceiling((double)postMem % preMem));
                        RConsole.WriteLine("Gridding Data Into Tiles {0}/{1} {2}", tiles_x, tiles_y, "- Memory Used: " + calMem);

                        preMem = GC.GetTotalMemory(true);

                        int reportStep      = 0;
                        int pointsProcessed = 0;
                        int interval        = points.Length > 1000000
                                    ? 1000000 : points.Length > 100000
                                    ? 10000 : points.Length > 10000
                                    ? 10000 : points.Length > 1000
                                    ? 1000 : points.Length > 100
                                    ? 100 : points.Length > 10
                                    ? 10 : 10;

                        while (set.MoveNext())
                        {
                            pointsProcessed++;

                            if (reportStep++ % interval == 0)
                            {
                                var percent = Clamp((int)Math.Ceiling(
                                                        (double)pointsProcessed * 100
                                                        / points.Length), 0, 100);
                            }



                            var point = (TcLasPointBase)set.Current;

                            if (point.ReturnNumber != point.NumberOfReturns)
                            {
                                continue;
                            }


                            var x = Math.Round(point.X, 2);
                            var y = Math.Round(point.Y, 2);
                            var z = Math.Round(point.Z, 2);

                            var X = (int)(x - (x % (TS * factor)));
                            var Y = (int)(y - (y % (TS * factor)));
                            var J = (int)(X - minX) / (TS * factor);
                            var I = (int)(Y - minY) / (TS * factor);

                            options.Buffer = Clamp(options.Buffer, 1, 20);

                            J = Clamp(J, 0, tiles_x - options.Buffer);
                            I = Clamp(I, 0, tiles_y - options.Buffer);

                            if (Tiles[J, I] == null)
                            {
                                Tiles[J, I] = new Tile
                                {
                                    East  = J,
                                    North = I,
                                };

                                Tiles[J, I].XVertices.Add(x);
                                Tiles[J, I].YVertices.Add(y);
                                Tiles[J, I].ZVertices.Add(z);
                            }
                            else
                            {
                                Tiles[J, I].XVertices.Add(x);
                                Tiles[J, I].YVertices.Add(y);
                                Tiles[J, I].ZVertices.Add(z);
                            }
                        }

                        s.Stop();

                        postMem = GC.GetTotalMemory(true);
                        calMem  = ToReadableMemUnit((int)Math.Ceiling((double)postMem % preMem));

                        RConsole.WriteLine("Gridded Data Into {0} Tiles - Finished {1} secs - Memory Used: {2}", true, Tiles.Length, Math.Ceiling((double)s.ElapsedMilliseconds / 1000)
                                           , calMem);
                        #endregion
                    }
                    #endregion
                }
                catch (Exception error)
                {
                    RConsole.WriteLine("Error Las Reader / Pre Gridder\n {0}\n{1}\n{2}",
                                       error.StackTrace,
                                       error.Source,
                                       error.Message);


                    return;
                }
                finally
                {
                    fs.Stop();
                    RConsole.WriteLine("Job Completed - {0} secs - {1}", Math.Ceiling((double)fs.ElapsedMilliseconds / 1000), DateTime.Now.ToString());
                }

                try
                {
                    #region Extracting Planars
                    GC.Collect();
                    GC.SuppressFinalize(Tiles);
                    preMem = GC.GetTotalMemory(true);
                    calMem = ToReadableMemUnit((int)Math.Ceiling((double)postMem % preMem));
                    RConsole.WriteLine("{0} Memory Truncated. ", true, calMem);


                    preMem = GC.GetTotalMemory(true);
                    RConsole.WriteLine("{0}", true, "Detecting Planar Surfaces");


                    var sw = Stopwatch.StartNew();

                    if (Tiles.GetLength(0) == 0 ||
                        Tiles.GetLength(1) == 0)
                    {
                        return;
                    }

                    var width          = Tiles.GetLength(0);
                    var height         = Tiles.GetLength(1);
                    var processed      = 0;
                    var tinterval      = height > 100 ? 100 : 10;
                    var removed        = 0;
                    var sigmas         = new List <double>();
                    var hvalues        = new List <double>();
                    var hinterval      = 3;
                    var tilesprocessed = 0;

                    for (int j = 0; j < height; j++)
                    {
                        for (int i = 0; i < width; i++)
                        {
                            if (Tiles[i, j] != null)
                            {
                                var tile      = Tiles[i, j];
                                var heights   = new List <Double>();
                                var maxHeight = Double.MinValue;
                                var minHeight = Double.MaxValue;

                                foreach (var h in tile.ZVertices)
                                {
                                    heights.Add(h);
                                    maxHeight = Math.Max(maxHeight, h);
                                    minHeight = Math.Min(minHeight, h);
                                }

                                //filter out flat planars above .20cm tolerance.
                                if (heights.Count <= 2 || (maxHeight - minHeight > 0.20f))
                                {
                                    Tiles[i, j] = null;
                                    continue;
                                }


                                var avg     = TcMathUtil.Average(heights);
                                var stDev   = TcMathUtil.StDev(heights, avg);
                                var count   = 0;
                                var sum     = 0.0;
                                var indices = new List <double>();


                                for (int p = 0; p < heights.Count; p++)
                                {
                                    if (Math.Abs(heights[p] - avg) < 2 * stDev)
                                    {
                                        sum += heights[p];
                                        count++;
                                    }
                                    else
                                    {
                                        indices.Add(heights[p]);
                                    }
                                }

                                var result = count > 0
                                    ? sum / count : TcConstants.TorNullValue32Bit;

                                int k = 0;


                                while (k < tile.ZVertices.Count)
                                {
                                    if (!indices.Contains(Tiles[i, j].ZVertices[k]) &&
                                        result != TcConstants.TorNullValue32Bit)
                                    {
                                        Tiles[i, j].ZVertices[k] = result;
                                    }
                                    else
                                    {
                                        Tiles[i, j].XVertices.RemoveAt(k);
                                        Tiles[i, j].YVertices.RemoveAt(k);
                                        Tiles[i, j].ZVertices.RemoveAt(k);
                                        removed++;
                                    }

                                    k++;
                                }
                            }
                        }

                        if (processed++ % tinterval == 0)
                        {
                            var percent = Clamp(
                                (int)Math.Ceiling((double)processed * 100
                                                  / height), 0, 100);
                        }


                        if (tilesprocessed++ % hinterval == 0 && sigmas.Count > 0)
                        {
                            hvalues = new List <double>();
                            sigmas  = new List <double>();
                        }
                    }


                    preMem = GC.GetTotalMemory(true);
                    calMem = ToReadableMemUnit((int)Math.Ceiling((double)postMem % preMem));

                    RConsole.WriteLine("Non-Flat Points Removed From Data: {0}", removed);
                    RConsole.WriteLine("{0}", true, "Permuting Flat Points - Finished " + Math.Ceiling((double)sw.ElapsedMilliseconds / 1000)
                                       + " secs - Memory Used: " + calMem);

                    GC.Collect();
                    GC.SuppressFinalize(Tiles);
                    postMem = GC.GetTotalMemory(true);
                    calMem  = ToReadableMemUnit((int)Math.Ceiling((double)postMem % preMem));
                    RConsole.WriteLine("{0} Memory Truncated. ", true, calMem);


                    preMem = GC.GetTotalMemory(true);

                    RConsole.WriteLine("{0}", true, "Saving Planar Surfaces to " + options.OutputFile);
                    sw = Stopwatch.StartNew();


                    using (var sr = File.CreateText(options.OutputFile))
                    {
                        processed = 0;
                        tinterval = height > 100 ? 100 : 10;

                        for (int j = 0; j < height; j++)
                        {
                            for (int i = 0; i < width; i++)
                            {
                                if (Tiles[i, j] != null)
                                {
                                    var tile = Tiles[i, j];

                                    for (int p = 0; p < tile.XVertices.Count; p++)
                                    {
                                        sr.WriteLine("{0:000000.00} {1:000000.00} {2:000.00}",
                                                     tile.XVertices[p],
                                                     tile.YVertices[p],
                                                     tile.ZVertices[p]);
                                    }
                                }
                            }

                            if (processed++ % tinterval == 0)
                            {
                                var percent = Clamp(
                                    (int)Math.Ceiling((double)processed * 100
                                                      / height), 0, 100);
                            }
                        }
                    }

                    sw.Stop();

                    preMem = GC.GetTotalMemory(true);
                    calMem = ToReadableMemUnit((int)Math.Ceiling((double)postMem % preMem));


                    RConsole.WriteLine("Saved permuted flat points - Finished {1} secs - Memory Used: {2}", true, Tiles.Length, Math.Ceiling((double)sw.ElapsedMilliseconds / 1000)
                                       , calMem);



                    preMem = GC.GetTotalMemory(true);
                    GC.Collect();
                    GC.SuppressFinalize(Tiles);
                    postMem = GC.GetTotalMemory(true);
                    calMem  = ToReadableMemUnit((int)Math.Ceiling((double)postMem % preMem));
                    RConsole.WriteLine("{0} Memory Truncated. ", true, calMem);
                    #endregion
                }
                catch (Exception error)
                {
                    RConsole.WriteLine("Error Flattening\n {0}\n{1}\n{2}",
                                       error.StackTrace,
                                       error.Source,
                                       error.Message);


                    return;
                }
                finally
                {
                    fs.Stop();
                    RConsole.WriteLine("Job Completed - {0} secs - {1}", Math.Ceiling((double)fs.ElapsedMilliseconds / 1000), DateTime.Now.ToString());
                }
            }
            else
            {
                options.GetUsage();
            }
        }
Exemplo n.º 11
0
        //-----------------------------------------------------------------------------

        private void ProcessTiles <T>(TcLasReader prmReader, String prmOutput) where T : TiLasPoint
        {
            // Variables to be used inside the big loop.
            Int32 tileOffset      = 0;
            Int32 index           = -1;
            Int32 pointsProcessed = 0;

            // Key: Index of the Tile, Value: Array of 1000 points.
            Dictionary <Int32, T[]> m_TileBlocks = new Dictionary <Int32, T[]>();

            TiLasHeader newHeader = UpdateTileCounts <T>(prmReader.Header, TileSize);

            Byte[] offsetBytes = prmReader.OffsetBytes;

            String blockFile = String.Format(@"{0}\{1}.xml", Path.GetDirectoryName(prmOutput), Path.GetFileNameWithoutExtension(prmOutput));

            if (File.Exists(blockFile))
            {
                File.Delete(blockFile);
            }

            using (TcLasWriter writer = new TcLasWriter(prmOutput)
            {
                MinClampZ = MinClampZ, MaxClampZ = MaxClampZ,
                /* Added By Dean */ ZAdjustment = this.ZAdjustment, XAdjustment = this.XAdjustment, YAdjustment = this.YAdjustment
            })
            {
                writer.WriteHeader(newHeader, offsetBytes);
                Int64     numberOfPointRecords = GetNumberOfPoints(prmReader.Header);
                Int32     onePercent           = (Int32)numberOfPointRecords / 100;
                Int32[]   rowCol = new Int32[2];
                DateTime  now = DateTime.Now;
                Boolean[] availIndices = new Boolean[m_TileBlockInfoCollection.TileInfo.Row * m_TileBlockInfoCollection.TileInfo.Col];
                Double    x, y;
                Double    z = 0; // Added Z Property  - Dean


                Int64 noOfPointsLoaded = 0;
                Int64 noOfPointsToRead = 0;
                while (noOfPointsLoaded < numberOfPointRecords)
                {
                    noOfPointsToRead = Math.Min(TcConstants.MaxLasPointsToProcessAtOnce, numberOfPointRecords - noOfPointsLoaded);
                    T[] loadedPoints = prmReader.ReadPoints <T>(noOfPointsToRead);
                    noOfPointsLoaded += noOfPointsToRead;

                    for (int i = 0; i < noOfPointsToRead; i++)
                    {
                        x = loadedPoints[i].X * newHeader.XScaleFactor + newHeader.XOffset + XAdjustment;
                        y = loadedPoints[i].Y * newHeader.YScaleFactor + newHeader.YOffset + YAdjustment;

                        //added by dean
                        z = loadedPoints[i].Z * newHeader.ZScaleFactor + newHeader.ZOffset + ZAdjustment;

                        if (x <= 0 || y <= 0)
                        {
                            continue;
                        }

                        // Calculate the tile index for the point.
                        tileOffset = TileSize * Factor;
                        rowCol     = TcMathUtil.GetRowCol(x, y, m_RevisedEast, m_RevisedNorth, tileOffset, tileOffset);
                        index      = rowCol[1] * m_TileRows + rowCol[0];

                        if (!availIndices[index])
                        {
                            m_TileBlocks[index]      = new T[PointBlockSize];
                            m_BlockPointCount[index] = 0;
                            availIndices[index]      = true;
                        }

                        // Convert the int XY back with adjusted values.
                        loadedPoints[i].X = (Int32)((x - newHeader.XOffset) / newHeader.XScaleFactor);
                        loadedPoints[i].Y = (Int32)((y - newHeader.YOffset) / newHeader.YScaleFactor);
                        loadedPoints[i].Z = (Int32)((z - newHeader.ZOffset) / newHeader.ZScaleFactor);

                        m_TileBlocks[index][m_BlockPointCount[index]] = loadedPoints[i];
                        m_BlockPointCount[index]++;

                        // When a tile block is full, write into file and remove the points.
                        if (m_BlockPointCount[index] == PointBlockSize)
                        {
                            // writer.WritePoints<T>(m_TileBlocks[index], PointBlockSize);
                            writer.WritePointsWithOptions <T>(m_TileBlocks[index], ref newHeader, PointBlockSize);
                            ProcessTileBlock <T>(m_TileBlocks, rowCol[0], rowCol[1], index, pointsProcessed);
                            pointsProcessed    += PointBlockSize;
                            availIndices[index] = false;
                        }
                    }
                }

                // Process the remaining blocks with incomplete size.
                int row, col;
                foreach (Int32 idx in m_TileBlocks.Keys.ToList())
                {
                    row = idx % m_TileRows;
                    col = (idx - row) / m_TileRows;

                    writer.WritePointsWithOptions <T>(m_TileBlocks[idx], ref newHeader, m_BlockPointCount[idx]);
                    ProcessTileBlock <T>(m_TileBlocks, row, col, idx, pointsProcessed);
                    pointsProcessed += m_BlockPointCount[idx];
                }

                // Write the updated header.
                writer.WriteHeader(newHeader);

                TcTileUtils.SaveTileBlocks(m_TileBlockInfoCollection, blockFile);
            }
        }
Exemplo n.º 12
0
        //-----------------------------------------------------------------------------

        public void LasToCls(String prmInput, String prmOutput)
        {
            try
            {
                if (!File.Exists(prmInput))
                {
                    throw new FileNotFoundException("LAS file not found");
                }

                if (!Path.GetExtension(prmInput).Contains("las"))
                {
                    throw new InvalidDataException("Invalid input file format");
                }

                if (!Path.GetExtension(prmOutput).Contains(TcEnums.ShortName(m_Type)))
                {
                    throw new InvalidDataException("Invalid output file format");
                }

                using (TcLasReader reader = new TcLasReader(prmInput))
                {
                    switch (reader.Header.PointDataFormatID)
                    {
                    case 0:
                        LasToCls <TsLasPoint0>(reader, prmOutput);
                        break;

                    case 1:
                        LasToCls <TsLasPoint1>(reader, prmOutput);
                        break;

                    case 2:
                        LasToCls <TsLasPoint2>(reader, prmOutput);
                        break;

                    case 3:
                        LasToCls <TsLasPoint3>(reader, prmOutput);
                        break;

                    case 4:
                        LasToCls <TsLasPoint4>(reader, prmOutput);
                        break;

                    case 5:
                        LasToCls <TsLasPoint5>(reader, prmOutput);
                        break;

                    case 6:
                        LasToCls <TsLasPoint6>(reader, prmOutput);
                        break;

                    case 7:
                        LasToCls <TsLasPoint7>(reader, prmOutput);
                        break;

                    case 8:
                        LasToCls <TsLasPoint8>(reader, prmOutput);
                        break;

                    case 9:
                        LasToCls <TsLasPoint9>(reader, prmOutput);
                        break;

                    case 10:
                        LasToCls <TsLasPoint10>(reader, prmOutput);
                        break;

                    default:
                        throw new FormatException("Couldn't produce the file. LAS format not supported");
                    }
                }
            }
            catch (Exception ex)
            {
                ReportError("Failed to convert LAS file into Acl", ex);
            }
        }