LAS-Read/LASRead/LASFormat/PointDataRecord.cs

715 lines
28 KiB
C#
Raw Normal View History

2021-03-13 21:31:51 +13:00
using System;
using System.Collections;
using System.Text;
namespace LASRead.LASFormat
{
/// <summary>
/// LAS Data Payloads are in the Point Data Record (PDR) format <br />
/// PDR 0-5 share the same basic substructure (which is inherited from this interface, <br />
/// PDR 6-10 share a slightly different substructure (more flags)
/// </summary>
public interface IPointDataRecord
{
int X { get; set; }
int Y { get; set; }
int Z { get; set; }
Nullable<ushort> Intensity { get; set; }
byte ReturnNumberFlag_value { get; set; }
byte NumberOfReturnsFlag_value { get; set; }
byte ScanDirectionFlag_value { get; set; }
byte EdgeOfFlightLineFlag_value { get; set; }
byte Classification { get; set; }
sbyte ScanAngleRank { get; set; }
Nullable<byte> UserData { get; set; }
ushort PointSourceID { get; set; }
bool ReadPoint(byte[] data);
/// <summary>
/// Reads the flags from the supplied byte
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
bool ReadFlag(Tuple<byte, byte> source);
/// <summary>
/// Generates a new payload object from the supplied data bytes
/// </summary>
/// <param name="data">Well-formed byte data (i.e. Read from file)</param>
/// <returns>A new payload object t</returns>
IPointDataRecord ParsePoint(byte[] data);
byte[] MergeFlags();
byte[] GetAsByteArray();
}
class PDR0 : IPointDataRecord
{
int x;
int y;
int z;
ushort? intensity;
byte returnNumberFlag_value;
byte numberOfReturnsFlag_value;
byte scanDirectionFlag_value;
byte edgeOfFlightLineFlag_value;
byte classification;
sbyte scanAngleRank;
byte? userData;
ushort pointSourceID;
public static readonly int headerSize = 20;
public int X { get => x; set => x = value; }
public int Y { get => y; set => y = value; }
public int Z { get => z; set => z = value; }
public ushort? Intensity { get => intensity; set => intensity = value; }
public byte ReturnNumberFlag_value { get => returnNumberFlag_value; set => returnNumberFlag_value = value; }
public byte NumberOfReturnsFlag_value { get => numberOfReturnsFlag_value; set => numberOfReturnsFlag_value = value; }
public byte ScanDirectionFlag_value { get => scanDirectionFlag_value; set => scanDirectionFlag_value = value; }
public byte EdgeOfFlightLineFlag_value { get => edgeOfFlightLineFlag_value; set => edgeOfFlightLineFlag_value = value; }
public byte Classification { get => classification; set => classification = value; }
public sbyte ScanAngleRank { get => scanAngleRank; set => scanAngleRank = value; }
public byte? UserData { get => userData; set => userData = value; }
public ushort PointSourceID { get => pointSourceID; set => pointSourceID = value; }
public virtual bool ReadFlag(Tuple<byte, byte> source)
{
// Note that typical Windows environments should be Little Endian; matching the expected data format.
// This means for the number 3,
// 7-6-5-4 3-2-1-0
// 0 0 0 0 0 0 1 1
// So return number flag = 2-1-0 (011) = 3
const byte full = 255;
ReturnNumberFlag_value = (byte)(source.Item1 & (full >> 5)); // Right-shift mask by 5 to get only the first 3 bits
NumberOfReturnsFlag_value = (byte)((source.Item1 >> 3) & (full >> 5)); // Right shift by 3, and & with 3 to get the returns
ScanDirectionFlag_value = (byte)((source.Item1 >> 6) & (full >> 7));
EdgeOfFlightLineFlag_value = (byte)(source.Item1 >> 7);
/* Big Endian
ReturnNumberFlag_value = (byte)((source.Item1 >> 5)& (full >> 5)); // Right-shift by 5 to get only the first 3 bits
NumberOfReturnsFlag_value = (byte)((source.Item1 >> 2) & (full >> 5)); // Right shift by 3, and & with 3 to get the returns
ScanDirectionFlag_value = (byte)((source.Item1 >> 1) & (full >> 7));
EdgeOfFlightLineFlag_value = (byte)(source.Item1 & (full >> 7)); */
return true;
}
public virtual bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
x = BitConverter.ToInt32(data, 0);
y = BitConverter.ToInt32(data, 4);
z = BitConverter.ToInt32(data, 8);
intensity = BitConverter.ToUInt16(data, 12);
ReadFlag(Tuple.Create(data[14], (byte)0));
classification = data[15];
scanAngleRank = (sbyte)data[16];
userData = data[17];
pointSourceID = BitConverter.ToUInt16(data, 18);
return true;
}
else return false;
}
public static bool VerifySize(byte[] source, int headerSize)
{
if (source.Length < headerSize)
{
return false;
}
return true;
}
public virtual IPointDataRecord ParsePoint(byte[] data)
{
PDR0 newPoint = new PDR0();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(string.Format("Point: {0}, {1}, {2} {3}", X, Y, Z, Environment.NewLine));
sb.Append("Intensity: " + Intensity.ToString() + Environment.NewLine);
sb.Append("Return Number: " + ReturnNumberFlag_value.ToString() + Environment.NewLine);
sb.Append("Number of Returns: " + NumberOfReturnsFlag_value.ToString() + Environment.NewLine);
sb.Append("Scan Direction: " + (returnNumberFlag_value == 0 ? "+" : "-") + Environment.NewLine);
sb.Append("Edge of Flight Line: " + (returnNumberFlag_value == 0 ? "no" : "yes") + Environment.NewLine);
sb.Append("Classification: " + ((Classifications)Classification) + Environment.NewLine);
sb.Append("Scan Angle Rank: " + ScanAngleRank.ToString() + Environment.NewLine);
sb.Append("User Data: " + (userData == 0 ? "no" : "yes") + Environment.NewLine);
sb.Append("Point Data Source: " + PointSourceID.ToString() + Environment.NewLine);
return sb.ToString();
}
public byte[] MergeFlags()
{
int result = EdgeOfFlightLineFlag_value;
result |= ReturnNumberFlag_value << 5; // Right-shift mask by 5 to get only the first 3 bits
result |= NumberOfReturnsFlag_value << 3; // Right shift by 3, and & with 3 to get the returns
result |= ScanDirectionFlag_value << 2;
byte t = (byte)(result & 255);
return new byte[] { t };
}
public virtual byte[] GetAsByteArray()
{
byte[] result = new byte[headerSize];
BitConverter.GetBytes(X).CopyTo(result, 0);
BitConverter.GetBytes(Y).CopyTo(result, 4);
BitConverter.GetBytes(Y).CopyTo(result, 8);
BitConverter.GetBytes(Intensity ?? 0).CopyTo(result, 12);
MergeFlags().CopyTo(result, 14);
result[15] = Classification;
result[16] = (byte)scanAngleRank;
result[17] = userData ?? 0;
BitConverter.GetBytes(PointSourceID).CopyTo(result, 18);
return result;
}
}
class PDR1 : PDR0
{
double GPSTime;
new public static readonly int headerSize = 28;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
GPSTime = BitConverter.ToDouble(data, 20);
return true;
}
else return false;
}
public override IPointDataRecord ParsePoint(byte[] data)
{
PDR1 newPoint = new PDR1();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append("GPS Time: " + GPSTime.ToString() + Environment.NewLine);
return sb.ToString();
}
public override byte[] GetAsByteArray()
{
byte[] result = new byte[headerSize];
base.GetAsByteArray().CopyTo(result, 0);
BitConverter.GetBytes(GPSTime).CopyTo(result, 20);
return result;
}
}
class PDR2 : PDR0
{
ushort red;
ushort green;
ushort blue;
new public static readonly int headerSize = 26;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
red = BitConverter.ToUInt16(data, 20);
green = BitConverter.ToUInt16(data, 22);
blue = BitConverter.ToUInt16(data, 24);
return true;
}
else return false;
}
public override IPointDataRecord ParsePoint(byte[] data)
{
PDR2 newPoint = new PDR2();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append(string.Format("RGB: {0} {1} {2} {3}", red, green, blue, Environment.NewLine));
return sb.ToString();
}
public override byte[] GetAsByteArray()
{
byte[] result = new byte[headerSize];
base.GetAsByteArray().CopyTo(result, 0);
BitConverter.GetBytes(red).CopyTo(result, 20);
BitConverter.GetBytes(green).CopyTo(result, 22);
BitConverter.GetBytes(blue).CopyTo(result, 24);
return result;
}
}
class PDR3 : PDR1
{
ushort red;
ushort green;
ushort blue;
new public static readonly int headerSize = 34;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
red = BitConverter.ToUInt16(data, 28);
green = BitConverter.ToUInt16(data, 30);
blue = BitConverter.ToUInt16(data, 32);
return true;
}
else return false;
}
public override IPointDataRecord ParsePoint(byte[] data)
{
PDR3 newPoint = new PDR3();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append(string.Format("RGB: {0} {1} {2} {3}", red, green, blue, Environment.NewLine));
return sb.ToString();
}
public override byte[] GetAsByteArray()
{
byte[] result = new byte[headerSize];
base.GetAsByteArray().CopyTo(result, 0);
BitConverter.GetBytes(red).CopyTo(result, 28);
BitConverter.GetBytes(green).CopyTo(result, 30);
BitConverter.GetBytes(blue).CopyTo(result, 32);
return result;
}
}
class PDR4 : PDR1
{
byte wavePacketDescriptorIndex;
ulong WaveformOffset;
uint WaveformSize;
float returnPointWaveform;
float dx;
float dy;
float dz;
new public static readonly int headerSize = 57;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
wavePacketDescriptorIndex = data[28];
WaveformOffset = BitConverter.ToUInt64(data, 29);
WaveformSize = BitConverter.ToUInt32(data, 37);
returnPointWaveform = BitConverter.ToSingle(data, 41);
dx = BitConverter.ToSingle(data, 45);
dy = BitConverter.ToSingle(data, 49);
dz = BitConverter.ToSingle(data, 53);
return true;
}
else return false;
}
public override IPointDataRecord ParsePoint(byte[] data)
{
PDR4 newPoint = new PDR4();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append("WavePacket Index: " + wavePacketDescriptorIndex.ToString() + Environment.NewLine);
sb.Append("Waveform Offset: " + WaveformOffset.ToString() + Environment.NewLine);
sb.Append("Waveform Size: " + WaveformSize.ToString() + Environment.NewLine);
sb.Append("Return Point Waveform: " + returnPointWaveform.ToString() + Environment.NewLine);
sb.Append(string.Format("Delta Pos: dx={0} dy={1} dz={2} {3}", dx, dy, dz, Environment.NewLine));
return sb.ToString();
}
public override byte[] GetAsByteArray()
{
byte[] result = new byte[headerSize];
base.GetAsByteArray().CopyTo(result, 0);
result[28] = wavePacketDescriptorIndex;
BitConverter.GetBytes(WaveformOffset).CopyTo(result, 29);
BitConverter.GetBytes(WaveformSize).CopyTo(result, 37);
BitConverter.GetBytes(returnPointWaveform).CopyTo(result, 41);
BitConverter.GetBytes(dx).CopyTo(result, 45);
BitConverter.GetBytes(dy).CopyTo(result, 49);
BitConverter.GetBytes(dz).CopyTo(result, 53);
return result;
}
}
class PDR5 : PDR3
{
byte wavePacketDescriptorIndex;
ulong WaveformOffset;
uint WaveformSize;
float returnPointWaveform;
float dx;
float dy;
float dz;
new public static readonly int headerSize = 63;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
wavePacketDescriptorIndex = data[34];
WaveformOffset = BitConverter.ToUInt64(data, 35);
WaveformSize = BitConverter.ToUInt32(data, 43);
returnPointWaveform = BitConverter.ToSingle(data, 47);
dx = BitConverter.ToSingle(data, 51);
dy = BitConverter.ToSingle(data, 55);
dz = BitConverter.ToSingle(data, 59);
return true;
}
else return false;
}
public static new IPointDataRecord ParsePoint(byte[] data)
{
PDR5 newPoint = new PDR5();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append("WavePacket Index: " + wavePacketDescriptorIndex.ToString() + Environment.NewLine);
sb.Append("Waveform Offset: " + WaveformOffset.ToString() + Environment.NewLine);
sb.Append("Waveform Size: " + WaveformSize.ToString() + Environment.NewLine);
sb.Append("Return Point Waveform: " + returnPointWaveform.ToString() + Environment.NewLine);
sb.Append(string.Format("Delta Pos: dx={0} dy={1} dz={2} {3}", dx, dy, dz, Environment.NewLine));
return sb.ToString();
}
public override byte[] GetAsByteArray()
{
byte[] result = new byte[headerSize];
base.GetAsByteArray().CopyTo(result, 0);
result[34] = wavePacketDescriptorIndex;
BitConverter.GetBytes(WaveformOffset).CopyTo(result, 35);
BitConverter.GetBytes(WaveformSize).CopyTo(result, 43);
BitConverter.GetBytes(returnPointWaveform).CopyTo(result, 47);
BitConverter.GetBytes(dx).CopyTo(result, 51);
BitConverter.GetBytes(dy).CopyTo(result, 55);
BitConverter.GetBytes(dz).CopyTo(result, 59);
return result;
}
}
class PDR6 : IPointDataRecord
{
int x;
int y;
int z;
ushort? intensity;
byte returnNumberFlag_value; // NB: 4 bits here
byte numberOfReturnsFlag_value; // 4
byte classificationFlag_value; // 4
byte scannerChannelFlag_value; // 2
byte scanDirectionFlag_value; // 1
byte edgeOfFlightLineFlag_value; // 1
byte classification;
short scanAngleRank;
byte? userData;
ushort pointSourceID;
double GPSTime;
public static readonly int headerSize = 30;
// Inherited members
public int X { get => x; set => x = value; }
public int Y { get => y; set => y = value; }
public int Z { get => z; set => z = value; }
public ushort? Intensity { get => intensity; set => intensity = value; }
public byte ReturnNumberFlag_value { get => returnNumberFlag_value; set => returnNumberFlag_value = value; }
public byte NumberOfReturnsFlag_value { get => numberOfReturnsFlag_value; set => numberOfReturnsFlag_value = value; }
public byte ScanDirectionFlag_value { get => scanDirectionFlag_value; set => scanDirectionFlag_value = value; }
public byte EdgeOfFlightLineFlag_value { get => edgeOfFlightLineFlag_value; set => edgeOfFlightLineFlag_value = value; }
public byte Classification { get => classification; set => classification = value; }
public short ScanAngleRank { get => scanAngleRank; set => scanAngleRank = value; }
public byte? UserData { get => userData; set => userData = value; }
public ushort PointSourceID { get => pointSourceID; set => pointSourceID = value; }
// Local members
public byte ClassificationFlag_value { get => classificationFlag_value; set => classificationFlag_value = value; }
public byte ScannerChannelFlag_value { get => scannerChannelFlag_value; set => scannerChannelFlag_value = value; }
public double GPSTime1 { get => GPSTime; set => GPSTime = value; }
sbyte IPointDataRecord.ScanAngleRank { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public bool ReadFlag(Tuple<byte, byte> source)
{
const byte full = 255;
ReturnNumberFlag_value = (byte)(source.Item1 & (full << 4));
NumberOfReturnsFlag_value = (byte)((source.Item1 >> 4) & (full << 4));
ClassificationFlag_value = (byte)(source.Item2 & (full << 4));
ScannerChannelFlag_value = (byte)((source.Item2 >> 4) & (full << 2));
ScanDirectionFlag_value = (byte)((source.Item2 >> 6) & (full << 1));
EdgeOfFlightLineFlag_value = (byte)(source.Item2 >> 7);
return true;
}
public virtual bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
x = BitConverter.ToInt32(data, 0);
y = BitConverter.ToInt32(data, 4);
z = BitConverter.ToInt32(data, 8);
intensity = BitConverter.ToUInt16(data, 12);
ReadFlag(Tuple.Create(data[14], data[15]));
classification = data[16];
userData = data[17];
scanAngleRank = BitConverter.ToInt16(data, 18);
pointSourceID = BitConverter.ToUInt16(data, 20);
return true;
}
else return false;
}
public virtual IPointDataRecord ParsePoint(byte[] data)
{
PDR6 newPoint = new PDR6();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(string.Format("Point: {0}, {1}, {2} {3}", X, Y, Z, Environment.NewLine));
sb.Append("Intensity: " + Intensity.ToString() + Environment.NewLine);
sb.Append("Return Number: " + ReturnNumberFlag_value.ToString() + Environment.NewLine);
sb.Append("Number of Returns: " + NumberOfReturnsFlag_value.ToString() + Environment.NewLine);
sb.Append("Classification Value: " + ClassificationFlag_value + Environment.NewLine);
sb.Append("Scanner Channel Value: " + ScannerChannelFlag_value + Environment.NewLine);
sb.Append("Scan Direction: " + (returnNumberFlag_value == 0 ? "+" : "-") + Environment.NewLine);
sb.Append("Edge of Flight Line: " + (returnNumberFlag_value == 0 ? "no" : "yes") + Environment.NewLine);
sb.Append("Classification: " + ((Classifications)Classification) + Environment.NewLine);
sb.Append("Scan Angle Rank: " + ScanAngleRank.ToString() + Environment.NewLine);
sb.Append("User Data: " + (userData == 0 ? "no" : "yes") + Environment.NewLine);
sb.Append("Point Data Source: " + PointSourceID.ToString() + Environment.NewLine);
sb.Append("GPS Time: " + GPSTime1.ToString() + Environment.NewLine);
return sb.ToString();
}
public byte[] MergeFlags()
{
int result = EdgeOfFlightLineFlag_value;
result |= ReturnNumberFlag_value << 5; // Right-shift mask by 5 to get only the first 3 bits
result |= NumberOfReturnsFlag_value << 3; // Right shift by 3, and & with 3 to get the returns
result |= ScanDirectionFlag_value << 2;
byte t = (byte)(result & 255);
throw new NotImplementedException();
return new byte[] { t };
}
public virtual byte[] GetAsByteArray()
{
byte[] result = new byte[headerSize];
BitConverter.GetBytes(X).CopyTo(result, 0);
BitConverter.GetBytes(Y).CopyTo(result, 4);
BitConverter.GetBytes(Y).CopyTo(result, 8);
BitConverter.GetBytes(Intensity ?? 0).CopyTo(result, 12);
MergeFlags().CopyTo(result, 14);
result[15] = Classification;
result[16] = (byte)scanAngleRank;
result[17] = userData ?? 0;
BitConverter.GetBytes(PointSourceID).CopyTo(result, 18);
return result;
}
}
class PDR7 : PDR6
{
ushort red;
ushort green;
ushort blue;
new public static readonly int headerSize = 36;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
red = BitConverter.ToUInt16(data, 30);
green = BitConverter.ToUInt16(data, 32);
blue = BitConverter.ToUInt16(data, 34);
return true;
}
else return false;
}
public override IPointDataRecord ParsePoint(byte[] data)
{
PDR7 newPoint = new PDR7();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append(string.Format("RGB: {0} {1} {2} {3}", red, green, blue, Environment.NewLine));
return sb.ToString();
}
}
class PDR8 : PDR7
{
ushort nIR;
new public static readonly int headerSize = 38;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
nIR = BitConverter.ToUInt16(data, 36);
return true;
}
else return false;
}
public override IPointDataRecord ParsePoint(byte[] data)
{
PDR8 newPoint = new PDR8();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append("Infrared: " + nIR.ToString() + Environment.NewLine);
return sb.ToString();
}
}
class PDR9 : PDR6
{
byte wavePacketDescriptorIndex;
ulong byteOffsetToWaveformData;
uint waveformPacketSize;
float returnPointWaveformLocation;
float dx;
float dy;
float dz;
new public static readonly int headerSize = 59;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
wavePacketDescriptorIndex = data[38];
byteOffsetToWaveformData = BitConverter.ToUInt64(data, 39);
waveformPacketSize = BitConverter.ToUInt32(data, 47);
returnPointWaveformLocation = BitConverter.ToSingle(data, 51);
dx = BitConverter.ToSingle(data, 55);
dy = BitConverter.ToSingle(data, 59);
dz = BitConverter.ToSingle(data, 63);
return true;
}
else return false;
}
public override IPointDataRecord ParsePoint(byte[] data)
{
PDR9 newPoint = new PDR9();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append("WavePacket Index: " + wavePacketDescriptorIndex.ToString() + Environment.NewLine);
sb.Append("Waveform Offset: " + byteOffsetToWaveformData.ToString() + Environment.NewLine);
sb.Append("Waveform Size: " + waveformPacketSize.ToString() + Environment.NewLine);
sb.Append("Return Point Waveform: " + returnPointWaveformLocation.ToString() + Environment.NewLine);
sb.Append(string.Format("Delta Pos: dx={0} dy={1} dz={2} {3}", dx, dy, dz, Environment.NewLine));
return sb.ToString();
}
}
class PDR10 : PDR8
{
byte wavePacketDescriptorIndex;
ulong byteOffsetToWaveformData;
uint waveformPacketSize;
float returnPointWaveformLocation;
float dx;
float dy;
float dz;
new public static readonly int headerSize = 67;
public override bool ReadPoint(byte[] data)
{
if (DataHelpers.VerifySize(data, headerSize))
{
base.ReadPoint(data);
wavePacketDescriptorIndex = data[30];
byteOffsetToWaveformData = BitConverter.ToUInt64(data, 31);
waveformPacketSize = BitConverter.ToUInt32(data, 39);
returnPointWaveformLocation = BitConverter.ToSingle(data, 43);
dx = BitConverter.ToSingle(data, 47);
dy = BitConverter.ToSingle(data, 51);
dz = BitConverter.ToSingle(data, 55);
return true;
}
else return false;
}
public override IPointDataRecord ParsePoint(byte[] data)
{
PDR10 newPoint = new PDR10();
newPoint.ReadPoint(data);
return newPoint;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append("WavePacket Index: " + wavePacketDescriptorIndex.ToString() + Environment.NewLine);
sb.Append("Waveform Offset: " + byteOffsetToWaveformData.ToString() + Environment.NewLine);
sb.Append("Waveform Size: " + waveformPacketSize.ToString() + Environment.NewLine);
sb.Append("Return Point Waveform: " + returnPointWaveformLocation.ToString() + Environment.NewLine);
sb.Append(string.Format("Delta Pos: dx={0} dy={1} dz={2} {3}", dx, dy, dz, Environment.NewLine));
return sb.ToString();
}
}
}