Base Shapefile shape - contains only the shape type and metadata plus helper methods. An instance of Shape is the Null ShapeType. If the Type field is not ShapeType.Null then cast to the more specific shape (i.e. ShapePolygon).
Exemplo n.º 1
0
        /// <summary>
        /// Creates a Shape object (or derived object) from a shape record
        /// </summary>
        /// <param name="shapeData">The shape record as a byte array</param>
        /// <param name="metadata">Metadata associated with this shape (optional)</param>
        /// <param name="dataRecord">IDataRecord associated with the metadata</param>
        /// <returns>A Shape, or derived class</returns>
        /// <exception cref="ArgumentNullException">Thrown if shapeData or metadata are null</exception>
        /// <exception cref="ArgumentException">Thrown if shapeData is less than 12 bytes long</exception>
        /// <exception cref="InvalidOperationException">Thrown if an error occurs parsing shapeData</exception>
        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;
        }