public static Shape ParseShape(byte[] shapeData, StringDictionary metadata, IDataRecord dataRecord)
{
if (shapeData == null)
{
throw new ArgumentNullException("shapeData");
}
if (shapeData.Length < 12)
{
throw new ArgumentException("shapeData must be at least 12 bytes long");
}
// shape data contains a header (shape number and content length)
// the first field in each shape is the shape type
//Position Field Value Type Order
//Byte 0 Record Number Record Number Integer Big
//Byte 4 Content Length Content Length Integer Big
//Position Field Value Type Number Order
//Byte 0 Shape Type Shape Type Integer 1 Little
int recordNumber = EndianBitConverter.ToInt32(shapeData, 0, ProvidedOrder.Big);
int contentLengthInWords = EndianBitConverter.ToInt32(shapeData, 4, ProvidedOrder.Big);
ShapeType shapeType = (ShapeType)EndianBitConverter.ToInt32(shapeData, 8, ProvidedOrder.Little);
// test that we have the expected amount of data - need to take the 8 byte header into account
if (shapeData.Length != (contentLengthInWords * 2) + 8)
{
throw new InvalidOperationException("Shape data length does not match shape header length");
}
Shape shape = null;
switch (shapeType)
{
case ShapeType.Null:
shape = new Shape(shapeType, recordNumber, metadata, dataRecord);
break;
case ShapeType.Point:
shape = new ShapePoint(recordNumber, metadata, dataRecord, shapeData);
break;
case ShapeType.MultiPoint:
shape = new ShapeMultiPoint(recordNumber, metadata, dataRecord, shapeData);
break;
case ShapeType.PolyLine:
shape = new ShapePolyLine(recordNumber, metadata, dataRecord, shapeData);
break;
case ShapeType.PolyLineM:
shape = new ShapePolyLineM(recordNumber, metadata, dataRecord, shapeData);
break;
case ShapeType.Polygon:
shape = new ShapePolygon(recordNumber, metadata, dataRecord, shapeData);
break;
case ShapeType.PolygonZ:
shape = new ShapePolygonZ(recordNumber, metadata, dataRecord, shapeData);
break;
default:
throw new NotImplementedException(string.Format("Shapetype {0} is not implemented", shapeType));
}
return shape;
}
}