689 lines
26 KiB
C#
689 lines
26 KiB
C#
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 formats 0-5 share the same basic substructure (which is ultimately inherited from this interface) <br />
|
|
/// PDR 6-10 share a slightly different substructure (more flags)
|
|
/// </summary>
|
|
public interface IPointDataRecord
|
|
{
|
|
public int X { get; set; }
|
|
public int Y { get; set; }
|
|
public int Z { get; set; }
|
|
|
|
public ushort? Intensity { get; set; }
|
|
public byte ReturnNumberFlag_value { get; set; }
|
|
public byte NumberOfReturnsFlag_value { get; set; }
|
|
public byte ScanDirectionFlag_value { get; set; }
|
|
public byte EdgeOfFlightLineFlag_value { get; set; }
|
|
public byte Classification { get; set; }
|
|
public sbyte ScanAngleRank { get; set; }
|
|
|
|
public byte? UserData { get; set; }
|
|
public ushort PointSourceID { get; set; }
|
|
public 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
|
|
{
|
|
const int headerSize = 20;
|
|
/// <summary>
|
|
/// PDRs for the X,Y,Z are 4-byte integers. They are multiplied by the scale defined in the
|
|
/// header to determine the true (potentially non-integral) coordinate of the point
|
|
/// </summary>
|
|
public int X { get; set; }
|
|
public int Y { get; set; }
|
|
public int Z { get; set; }
|
|
public ushort? Intensity { get; set; }
|
|
public byte ReturnNumberFlag_value { get; set; }
|
|
public byte NumberOfReturnsFlag_value { get; set; }
|
|
public byte ScanDirectionFlag_value { get; set; }
|
|
public byte EdgeOfFlightLineFlag_value { get; set; }
|
|
public byte Classification { get; set; }
|
|
public sbyte ScanAngleRank { get; set; }
|
|
public byte? UserData { get; set; }
|
|
public ushort PointSourceID { get; set; }
|
|
|
|
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;
|
|
const 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;
|
|
const 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;
|
|
const 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;
|
|
|
|
const 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;
|
|
|
|
const 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
|
|
{
|
|
const int headerSize = 30;
|
|
// Inherited members
|
|
public int X { get; set; }
|
|
public int Y { get; set; }
|
|
public int Z { get; set; }
|
|
public ushort? Intensity { get; set; }
|
|
public byte ReturnNumberFlag_value { get; set; }
|
|
public byte NumberOfReturnsFlag_value { get; set; }
|
|
public byte ScanDirectionFlag_value { get; set; }
|
|
public byte EdgeOfFlightLineFlag_value { get; set; }
|
|
public byte Classification { get; set; }
|
|
public short ScanAngleRank { get; set; }
|
|
public byte? UserData { get; set; }
|
|
public ushort PointSourceID { get; set; }
|
|
// Local members
|
|
public byte ClassificationFlag_value { get; set; }
|
|
public byte ScannerChannelFlag_value { get; set; }
|
|
public double GPSTime1 { get; set; }
|
|
|
|
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;
|
|
|
|
const 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;
|
|
|
|
const 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;
|
|
|
|
const 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;
|
|
|
|
const 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();
|
|
}
|
|
}
|
|
}
|