Пример #1
0
        //-----------------------------------------------------------------------------

        public void WritePoints <T>(T[] prmPoints, Int64 prmNoOfPoints = -1) where T : TiLasPoint
        {
            Int32 count     = prmNoOfPoints < 0 ? prmPoints.Length : (Int32)prmNoOfPoints;
            Int32 pointSize = Marshal.SizeOf(typeof(TsXYZLasPoint));
            Int32 totalSize = pointSize * count;

            // Allocates memory and totalPtr points to the 1st location.
            IntPtr totalPtr = Marshal.AllocHGlobal(totalSize);
            IntPtr structPtr;

            // Classification point.
            TsXYZLasPoint clsPoint;

            // This is used to increment the location of the pointer later. It cant be done with IntPtr.
            // ptrLoc points to the 1st location of totalPtr.
            Int64 ptrLoc = totalPtr.ToInt64();

            for (int i = 0; i < count; i++)
            {
                // Creating the classification point from the las point.
                clsPoint = new TsXYZLasPoint()
                {
                    X = prmPoints[i].X, Y = prmPoints[i].Y, Z = prmPoints[i].Z
                };

                // structPtr points to ptrLoc.
                structPtr = new IntPtr(ptrLoc);

                // Converts the structure into memory pointed by structPtr
                Marshal.StructureToPtr(clsPoint, structPtr, false);

                // Move the pointer.
                ptrLoc += pointSize;
            }

            byte[] buffer = new byte[totalSize];

            // Copies the data from totalPtr memory to arr array.
            Marshal.Copy(totalPtr, buffer, 0, totalSize);

            // Free the memory from the heap.
            Marshal.FreeHGlobal(totalPtr);

            // Write the array.
            m_ClsWriter.Write(buffer);
        }
Пример #2
0
        //-----------------------------------------------------------------------------

        /// <summary>
        /// This function reads a given number of points from the current location of the reader.
        /// If enough points not found in the file, it returns the available points.
        /// </summary>
        /// <typeparam name="T">Type of the las point</typeparam>
        /// <param name="prmNoOfPoints">Number of points to read</param>
        /// <returns>An array of LAS points</returns>
        public TsXYZLasPoint[] ReadPoints(Int64 prmNoOfPoints)
        {
            // Points loaded from file.
            Int64 noOfPointsLoaded = 0;

            // Points need to be loaded.
            Int64 noOfPointsToRead = 0;

            // No of bytes to read from the file.
            Int32 bytesToRead = 0;

            // Memory stream.
            Byte[] readBuffer;

            Int64 noOfPointsAvailable = (Int64)((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) / c_PointSize);

            prmNoOfPoints = Math.Min(prmNoOfPoints, noOfPointsAvailable);

            // Create a las point array of required size.
            TsXYZLasPoint[] returnBlocks = new TsXYZLasPoint[prmNoOfPoints];

            // Set a handle to the las point array.
            GCHandle pinnedHandle = GCHandle.Alloc(returnBlocks, GCHandleType.Pinned);

            // Pointer to the current pointed object.
            IntPtr blockPtr = pinnedHandle.AddrOfPinnedObject();

            // Value of the pointer.
            Int64 ptrLoc = blockPtr.ToInt64();

            try
            {
                while (noOfPointsLoaded < prmNoOfPoints)
                {
                    noOfPointsToRead = Math.Min(TcConstants.MaxLasPointsToProcessAtOnce, prmNoOfPoints - noOfPointsLoaded);

                    // Read required bytes from the file.
                    bytesToRead = c_PointSize * (Int32)noOfPointsToRead;
                    readBuffer  = m_Reader.ReadBytes(bytesToRead);

                    // Copy the stream to the structures.
                    Marshal.Copy(readBuffer, 0, blockPtr, bytesToRead);

                    // Update the processed item counter.
                    noOfPointsLoaded += noOfPointsToRead;

                    // Update the pointer value.
                    ptrLoc += bytesToRead;

                    // Move the pointer.
                    blockPtr = new IntPtr(ptrLoc);
                }

                return(returnBlocks);
            }
            finally
            {
                if (pinnedHandle.IsAllocated)
                {
                    pinnedHandle.Free();
                }

                readBuffer = new Byte[0];
            }
        }