/// <summary> /// Writes shapes. /// </summary> /// <param name="filename">The string value defining shape file name without .shp extension</param> /// <param name="geometryCollection"> MapAround.Geometry.GeometryCollection instance containing /// the geometries to write to shape file</param> public void WriteShapes(string filename, GeometryCollection geometryCollection) { if(geometryCollection.HasDifferentTypeInstances) throw new ArgumentException("Geometries in the shape file should be the instances of the same type.", "geometryCollection"); using (FileStream shpStream = new FileStream(filename + ".shp", FileMode.Create)) { using (FileStream shxStream = new FileStream(filename + ".shx", FileMode.Create)) { BigEndianBinaryWriter shpBinaryWriter = new BigEndianBinaryWriter(shpStream);//, Encoding.ASCII); BigEndianBinaryWriter shxBinaryWriter = new BigEndianBinaryWriter(shxStream);//, Encoding.ASCII); // body type and a handler Handlers.ShapeHandler handler = ShapeFile.GetShapeHandler(ShapeFile.GetShapeType(geometryCollection[0]));//.Geometries[0])); int numShapes = geometryCollection.Count; // calc the length of the shp file, so it can put in the header. int shpLength = 50; for (int i = 0; i < numShapes; i++) { IGeometry body = (IGeometry)geometryCollection[i];//.Geometries[i]; shpLength += 4; // length of header in WORDS shpLength += handler.GetLength(body); // length of shape in WORDS } int shxLength = 50 + (4 * numShapes); // write the .shp header ShapeFileHeader shpHeader = new ShapeFileHeader(); shpHeader.FileLength = shpLength; // get envelope in external coordinates BoundingRectangle bounds = geometryCollection.GetBoundingRectangle(); shpHeader.SetBounds(bounds); shpHeader.FileCode = 9994; shpHeader.ShapeType = (int)ShapeFile.GetShapeType(geometryCollection[0]);//.Geometries[0]); shpHeader.Write(shpBinaryWriter, ShapeFile.GetShapeType(geometryCollection[0])); // write the .shx header ShapeFileHeader shxHeader = new ShapeFileHeader(); shxHeader.FileLength = shxLength; shxHeader.SetBounds(shpHeader);//.Bounds = shpHeader.Bounds; // assumes Geometry type of the first item will the same for all other items in the collection. shxHeader.FileCode = 9994; shxHeader.ShapeType = (int)ShapeFile.GetShapeType(geometryCollection[0]); shxHeader.Write(shxBinaryWriter, ShapeFile.GetShapeType(geometryCollection[0])); // write the individual records. int _pos = 50; // header length in WORDS for (int i = 0; i < numShapes; i++) { IGeometry body = geometryCollection[i];//.Geometries[i]; int recordLength = handler.GetLength(body); shpBinaryWriter.WriteIntBE(i + 1); shpBinaryWriter.WriteIntBE(recordLength); shxBinaryWriter.WriteIntBE(_pos); shxBinaryWriter.WriteIntBE(recordLength); _pos += 4; // length of header in WORDS handler.Write(body, shpBinaryWriter);//, geometryFactory); _pos += recordLength; // length of shape in WORDS } shxBinaryWriter.Flush(); shxBinaryWriter.Close(); shpBinaryWriter.Flush(); shpBinaryWriter.Close(); } } }
/// <summary> /// Writes this header to the stream. /// </summary> /// <param name="file">A System.IO.BinaryWriter instance to write the header</param> /// <param name="ShapeType">Shape type</param> internal void Write(BigEndianBinaryWriter file, ShapeType ShapeType) { if (file == null) throw new ArgumentNullException("file"); if (this.FileLength == -1) throw new InvalidOperationException("The header properties need to be set before writing the header record."); int pos = 0; file.WriteIntBE(this.FileCode); pos += 4; for (int i = 0; i < 5; i++) { file.WriteIntBE(0);//Skip unused part of header pos += 4; } file.WriteIntBE(this.FileLength); pos += 4; file.Write(this.Version); pos += 4; file.Write(int.Parse(Enum.Format(typeof(ShapeType), ShapeType, "d"))); pos += 4; // Write the bounding box file.Write(this.MinX); file.Write(this.MinY); file.Write(this.MaxX); file.Write(this.MaxY); pos += 8 * 4; // Skip remaining unused bytes for (int i = 0; i < 4; i++) { file.Write(0.0); // Skip unused part of header pos += 8; } }