//----------------------------------------------------------------------------- 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); } }
//----------------------------------------------------------------------------- /// <summary> /// Open function to produce a list of grid files. /// </summary> /// <param name="prmInput">Input las file</param> /// <param name="prmGridTypes">List of grid types</param> /// <param name="prmGridSizes">List of grid sizes</param> public void Grid(String prmInput, IEnumerable <TeGriddingType> prmGridTypes, IEnumerable <Int32> prmGridSizes) { List <TcGridObject> gridObjects = new List <TcGridObject>(prmGridTypes.Count() + prmGridSizes.Count()); String xmlFile = String.Format(@"{0}\{1}.xml", Path.GetDirectoryName(prmInput), Path.GetFileNameWithoutExtension(prmInput)); m_Info = TcTileUtils.GetTileBlocks(xmlFile); // Type defined las tiling. foreach (TeGriddingType type in prmGridTypes) { String outputFile = String.Format(@"{0}\{1}_{2}.tor" , m_OutputDirectory , Path.GetFileNameWithoutExtension(prmInput) , TcEnums.ShortName(type)); gridObjects.Add(new TcGridObject(outputFile, type, m_Info)); } // Type defined las tiling. foreach (Int32 size in prmGridSizes.Distinct()) { String outputFile = String.Format(@"{0}\{1}_m{2}.tor" , m_OutputDirectory , Path.GetFileNameWithoutExtension(prmInput) , size); gridObjects.Add(new TcGridObject(outputFile, size, m_Info)); } Grid(prmInput, gridObjects); }
public TcIndexedLasInfo(String prmFile) { LasFile = prmFile; IndexFile = String.Format(@"{0}\{1}.xml", Path.GetDirectoryName(LasFile), Path.GetFileNameWithoutExtension(LasFile)); if (File.Exists(IndexFile)) { TileInfoCollection = TcTileUtils.GetTileBlocks(IndexFile); } }
//----------------------------------------------------------------------------- /// <summary> /// Open function to produce a single grid file with a given type. /// </summary> /// <param name="prmInput">Input las file</param> /// <param name="prmOutputFileName">Output tor file name</param> /// <param name="prmGridSize">Size of the grid</param> public void Grid(String prmInput, String prmOutputFileName, Int32 prmGridSize) { // Start of the actual function. String blockFile = String.Format(@"{0}\{1}.xml", Path.GetDirectoryName(prmInput), Path.GetFileNameWithoutExtension(prmInput)); m_Info = TcTileUtils.GetTileBlocks(blockFile); String outputFile = String.Format(@"{0}\{1}", m_OutputDirectory, prmOutputFileName); Grid(prmInput, new List <TcGridObject>(1) { new TcGridObject(outputFile, prmGridSize, m_Info) }); }
//----------------------------------------------------------------------------- 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); } } }
//----------------------------------------------------------------------------- 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); } }