/// <summary> /// Writes the current content to the specified file. /// </summary> /// <param name="destFilename">The string fileName to write to</param> /// <param name="destFileLength">The only difference between the shp header and the /// shx header is the file length parameter.</param> private void Write(string destFilename, int destFileLength) { string dir = Path.GetDirectoryName(Path.GetFullPath(Filename)); if (dir != null) if (!Directory.Exists(dir)) { //if (MessageBox.Show("Directory " + dir + " does not exist. Do you want to create it?", // "Create Directory?", MessageBoxButtons.YesNo) != DialogResult.OK) // return; Directory.CreateDirectory(dir); } //if (File.Exists(destFilename)) File.Delete(destFilename); FileStream fs = new FileStream(destFilename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); fs.WriteBe(_fileCode); // Byte 0 File Code 9994 Integer Big byte[] bt = new byte[20]; fs.Write(bt, 0, 20); // Bytes 4 - 20 are unused fs.WriteBe(destFileLength); // Byte 24 File Length File Length Integer Big fs.WriteLe(_version); // Byte 28 Version 1000 Integer Little fs.WriteLe((int)_shapeType); // Byte 32 Shape Type Shape Type Integer Little fs.WriteLe(_xMin); // Byte 36 Bounding Box Xmin Double Little fs.WriteLe(_yMin); // Byte 44 Bounding Box Ymin Double Little fs.WriteLe(_xMax); // Byte 52 Bounding Box Xmax Double Little fs.WriteLe(_yMax); // Byte 60 Bounding Box Ymax Double Little fs.WriteLe(_zMin); // Byte 68 Bounding Box Zmin Double Little fs.WriteLe(_zMax); // Byte 76 Bounding Box Zmax Double Little fs.WriteLe(_mMin); // Byte 84 Bounding Box Mmin Double Little fs.WriteLe(_mMax); // Byte 92 Bounding Box Mmax Double Little // ------------ WRITE TO SHP FILE ------------------------- fs.Close(); }
private void SaveAsIndexed(string fileName) { FileStream shpStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); FileStream shxStream = new FileStream(Header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); int fid = 0; int offset = 50; // the shapefile header starts at 100 bytes, so the initial offset is 50 words int contentLength = 0; foreach (ShapeRange shape in ShapeIndices) { offset += contentLength; // adding the previous content length from each loop calculates the word offset contentLength = 22; contentLength += 2 * shape.Parts.Count; switch (shape.ShapeType) { case ShapeType.PolyLine: contentLength += shape.NumPoints * 8; // x, y break; case ShapeType.PolyLineM: contentLength += 8; // mmin mmax contentLength += shape.NumPoints * 12; // x, y, m break; case ShapeType.PolyLineZ: contentLength += 16; // mmin, mmax, zmin, zmax contentLength += shape.NumPoints * 16; // x, y, z, m break; case ShapeType.NullShape: contentLength = 2; break; } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(fid + 1); // Byte 0 Record Number Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shpStream.WriteLe((int)shape.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (shape.ShapeType == ShapeType.NullShape) { goto fin; } shpStream.WriteLe(shape.Extent.MinX); // Byte 12 Xmin Double 1 Little shpStream.WriteLe(shape.Extent.MinY); // Byte 20 Ymin Double 1 Little shpStream.WriteLe(shape.Extent.MaxX); // Byte 28 Xmax Double 1 Little shpStream.WriteLe(shape.Extent.MaxY); // Byte 36 Ymax Double 1 Little shpStream.WriteLe(shape.NumParts); // Byte 44 NumParts Integer 1 Little shpStream.WriteLe(shape.NumPoints); // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little foreach (PartRange part in shape.Parts) { shpStream.WriteLe(part.PartOffset); } int start = shape.StartIndex; int count = shape.NumPoints; shpStream.WriteLe(Vertex, start * 2, count * 2); // Byte X Points Point NumPoints Little if (Header.ShapeType == ShapeType.PolyLineZ) { double[] shapeZ = new double[count]; Array.Copy(Z, start, shapeZ, 0, count); shpStream.WriteLe(shapeZ.Min()); shpStream.WriteLe(shapeZ.Max()); shpStream.WriteLe(Z, start, count); } if (Header.ShapeType == ShapeType.PolyLineM || Header.ShapeType == ShapeType.PolyLineZ) { if (M != null && M.Length >= start + count) { double[] shapeM = new double[count]; Array.Copy(M, start, shapeM, 0, count); shpStream.WriteLe(shapeM.Min()); shpStream.WriteLe(shapeM.Max()); shpStream.WriteLe(M, start, count); } } fin: fid++; offset += 4; // header bytes } shpStream.Close(); shxStream.Close(); offset += contentLength; //offset += 4; WriteFileLength(Filename, offset); WriteFileLength(Header.ShxFilename, 50 + fid * 4); UpdateAttributes(); SaveProjection(); }
/// <inheritdocs/> protected override void AppendBasicGeometry(ShapefileHeader header, IBasicGeometry feature, int numFeatures) { FileInfo fi = new FileInfo(Filename); int offset = Convert.ToInt32(fi.Length / 2); FileStream shpStream = new FileStream(Filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000); FileStream shxStream = new FileStream(header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 100); List<int> parts = new List<int>(); List<Coordinate> points = new List<Coordinate>(); int contentLength = 22; for (int iPart = 0; iPart < feature.NumGeometries; iPart++) { parts.Add(points.Count); IBasicLineString pg = feature.GetBasicGeometryN(iPart) as IBasicLineString; if (pg == null) continue; points.AddRange(pg.Coordinates); } contentLength += 2 * parts.Count; if (header.ShapeType == ShapeType.PolyLine) { contentLength += points.Count * 8; } if (header.ShapeType == ShapeType.PolyLineM) { contentLength += 8; // mmin mmax contentLength += points.Count * 12; // x, y, m } if (header.ShapeType == ShapeType.PolyLineZ) { contentLength += 16; // mmin, mmax, zmin, zmax contentLength += points.Count * 16; // x, y, m, z } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shxStream.Flush(); shxStream.Close(); // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(numFeatures); // Byte 0 Record Number Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shpStream.WriteLe((int)header.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (header.ShapeType == ShapeType.NullShape) { return; } shpStream.WriteLe(feature.Envelope.Minimum.X); // Byte 12 Xmin Double 1 Little shpStream.WriteLe(feature.Envelope.Minimum.Y); // Byte 20 Ymin Double 1 Little shpStream.WriteLe(feature.Envelope.Maximum.X); // Byte 28 Xmax Double 1 Little shpStream.WriteLe(feature.Envelope.Maximum.Y); // Byte 36 Ymax Double 1 Little shpStream.WriteLe(parts.Count); // Byte 44 NumParts Integer 1 Little shpStream.WriteLe(points.Count); // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little foreach (int iPart in parts) { shpStream.WriteLe(iPart); } double[] xyVals = new double[points.Count * 2]; int i = 0; foreach (Coordinate coord in points) { xyVals[i * 2] = coord.X; xyVals[i * 2 + 1] = coord.Y; i++; } shpStream.WriteLe(xyVals, 0, 2 * points.Count); if (header.ShapeType == ShapeType.PolyLineZ) { shpStream.WriteLe(feature.Envelope.Minimum.Z); shpStream.WriteLe(feature.Envelope.Maximum.Z); double[] zVals = new double[points.Count]; for (int ipoint = 0; ipoint < points.Count; ipoint++) { zVals[ipoint] = points[ipoint].Z; } shpStream.WriteLe(zVals, 0, points.Count); } if (header.ShapeType == ShapeType.PolyLineM || header.ShapeType == ShapeType.PolyLineZ) { if (feature.Envelope == null) { shpStream.WriteLe(0.0); shpStream.WriteLe(0.0); } else { shpStream.WriteLe(feature.Envelope.Minimum.M); shpStream.WriteLe(feature.Envelope.Maximum.M); } double[] mVals = new double[points.Count]; for (int ipoint = 0; ipoint < points.Count; i++) { mVals[ipoint] = points[ipoint].M; ipoint++; } shpStream.WriteLe(mVals, 0, points.Count); } shpStream.Flush(); shpStream.Close(); offset += contentLength; Shapefile.WriteFileLength(Filename, offset + 4); // Add 4 for the record header Shapefile.WriteFileLength(header.ShxFilename, 50 + numFeatures * 4); }
/// <summary> /// Saves the shapefile to a different fileName, but still as a shapefile. This method does not support saving to /// any other file format. /// </summary> /// <param name="fileName">The string fileName to save as</param> /// <param name="overwrite">A boolean that is true if the file should be overwritten</param> public override void SaveAs(string fileName, bool overwrite) { Filename = fileName; string dir = Path.GetDirectoryName(Path.GetFullPath(fileName)); if (dir != null && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } if (File.Exists(fileName)) { if (fileName != Filename && overwrite == false) throw new IOException("File exists."); File.Delete(fileName); string shx = Path.ChangeExtension(fileName, ".shx"); if (File.Exists(shx)) File.Delete(shx); } // comment out by keen edge as per this discussion // http://dotspatial.codeplex.com/Thread/View.aspx?ThreadId=234754 // InvalidateEnvelope(); // wordSize is the length of the byte representation in 16 bit words of a single shape, including header. int wordSize = 14; // 3 int(2) and 2 double(4) if (CoordinateType == CoordinateType.Regular) { Header.ShapeType = ShapeType.Point; } if (CoordinateType == CoordinateType.M) { Header.ShapeType = ShapeType.PointM; wordSize = 18; // 3 int(2), 3 double(4) } if (CoordinateType == CoordinateType.Z) { Header.ShapeType = ShapeType.PointZ; wordSize = 22; // 3 int(2), 4 double (4) } // Set Header.ShapeType before setting extent. Header.SetExtent(MyExtent); if (IndexMode) { Header.ShxLength = ShapeIndices.Count * 4 + 50; Header.FileLength = ShapeIndices.Count * wordSize + 50; } else { Header.ShxLength = Features.Count * 4 + 50; Header.FileLength = Features.Count * wordSize + 50; } Header.SaveAs(fileName); Stream shpStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.None, 1000000); Stream shxStream = new FileStream(Header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 1000000); // Special slightly faster writing for index mode if (IndexMode) { for (int shp = 0; shp < ShapeIndices.Count; shp++) { shpStream.WriteBe(shp + 1); shpStream.WriteBe(wordSize - 4); // shape word size without 4 shapeHeader words. shxStream.WriteBe(50 + shp * wordSize); shxStream.WriteBe(wordSize - 4); shpStream.WriteLe((int)Header.ShapeType); shpStream.WriteLe(Vertex[shp * 2]); shpStream.WriteLe(Vertex[shp * 2 + 1]); if (Z != null) shpStream.WriteLe(Z[shp]); if (M != null) shpStream.WriteLe(M[shp]); } } else { int fid = 0; foreach (IFeature f in Features) { Coordinate c = f.BasicGeometry.Coordinates[0]; shpStream.WriteBe(fid + 1); shpStream.WriteBe(wordSize - 4); shxStream.WriteBe(50 + fid * wordSize); shxStream.WriteBe(wordSize - 4); shpStream.WriteLe((int)Header.ShapeType); if (Header.ShapeType == ShapeType.NullShape) { continue; } shpStream.WriteLe(c.X); shpStream.WriteLe(c.Y); if (Header.ShapeType == ShapeType.PointZ) { shpStream.WriteLe(c.Z); } if (Header.ShapeType == ShapeType.PointM || Header.ShapeType == ShapeType.PointZ) { shpStream.WriteLe(c.M); } fid++; } } shpStream.Flush(); shpStream.Close(); shxStream.Flush(); shxStream.Close(); UpdateAttributes(); SaveProjection(); }
/// <summary> /// Saves the file to a new location /// </summary> /// <param name="fileName">The fileName to save</param> /// <param name="overwrite">Boolean that specifies whether or not to overwrite the existing file</param> private void SaveAsIndexed(string fileName, bool overwrite) { string dir = Path.GetDirectoryName(fileName); if (dir != null && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } if (File.Exists(fileName)) { if (fileName != Filename && overwrite == false) throw new IOException("File exists."); File.Delete(fileName); string shx = Path.ChangeExtension(fileName, ".shx"); if (File.Exists(shx)) File.Delete(shx); } if (CoordinateType == CoordinateType.Regular) { Header.ShapeType = ShapeType.MultiPoint; } if (CoordinateType == CoordinateType.M) { Header.ShapeType = ShapeType.MultiPointM; } if (CoordinateType == CoordinateType.Z) { Header.ShapeType = ShapeType.MultiPointZ; } Header.SetExtent(MyExtent); Header.ShxLength = ShapeIndices.Count * 4 + 50; Header.SaveAs(fileName); FileStream shpStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); FileStream shxStream = new FileStream(Header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); int fid = 0; int offset = 50; // the shapefile header starts at 100 bytes, so the initial offset is 50 words int contentLength = 0; foreach (ShapeRange shape in ShapeIndices) { offset += contentLength; // adding the previous content length from each loop calculates the word offset contentLength = 20; if (Header.ShapeType == ShapeType.MultiPoint) { contentLength += shape.NumPoints * 8; } if (Header.ShapeType == ShapeType.MultiPointM) { contentLength += 8; // mmin, mmax contentLength += shape.NumPoints * 12; } if (Header.ShapeType == ShapeType.MultiPointZ) { contentLength += 16; // mmin, mmax, zmin, zmax contentLength += shape.NumPoints * 16; } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Length Integer 1 Big // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(fid + 1); // Byte 0 Record Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Length Integer 1 Big shpStream.WriteLe((int)Header.ShapeType); // Byte 8 Type 3 Integer 1 Little if (Header.ShapeType == ShapeType.NullShape) { continue; } shpStream.WriteLe(shape.Extent.MinX); // Byte 12 Xmin Double 1 Little shpStream.WriteLe(shape.Extent.MinY); // Byte 20 Ymin Double 1 Little shpStream.WriteLe(shape.Extent.MaxX); // Byte 28 Xmax Double 1 Little shpStream.WriteLe(shape.Extent.MaxY); // Byte 36 Ymax Double 1 Little shpStream.WriteLe(shape.NumPoints); // Byte 44 #Points Integer 1 Little int start = shape.StartIndex; int count = shape.NumPoints; shpStream.WriteLe(Vertex, start * 2, count * 2); if (Header.ShapeType == ShapeType.MultiPointZ) { double[] shapeZ = new double[count]; Array.Copy(Z, start, shapeZ, 0, count); shpStream.WriteLe(shapeZ.Min()); shpStream.WriteLe(shapeZ.Max()); shpStream.WriteLe(Z, start, count); } if (Header.ShapeType == ShapeType.MultiPointM || Header.ShapeType == ShapeType.MultiPointZ) { if (M != null && M.Length >= start + count) { double[] shapeM = new double[count]; Array.Copy(M, start, shapeM, 0, count); shpStream.WriteLe(shapeM.Min()); shpStream.WriteLe(shapeM.Max()); shpStream.WriteLe(M, start, count); } } fid++; offset += 4; } shpStream.Flush(); shxStream.Flush(); shpStream.Close(); shxStream.Close(); offset += contentLength; WriteFileLength(Filename, offset); UpdateAttributes(); SaveProjection(); }
/// <summary> /// Saves the shapefile to a different fileName, but still as a shapefile. This method does not support saving to /// any other file format. /// </summary> /// <param name="fileName">The string fileName to save as</param> /// <param name="overwrite">A boolean that is true if the file should be overwritten</param> public override void SaveAs(string fileName, bool overwrite) { EnsureValidFileToSave(fileName, overwrite); Filename = fileName; // Set Header.ShapeType before setting extent. // wordSize is the length of the byte representation in 16 bit words of a single shape, including header. int wordSize = 14; // 3 int(2) and 2 double(4) if (CoordinateType == CoordinateType.Regular) { Header.ShapeType = ShapeType.Point; } if (CoordinateType == CoordinateType.M) { Header.ShapeType = ShapeType.PointM; wordSize = 18; // 3 int(2), 3 double(4) } if (CoordinateType == CoordinateType.Z) { Header.ShapeType = ShapeType.PointZ; wordSize = 22; // 3 int(2), 4 double (4) } InvalidateEnvelope(); Header.SetExtent(Extent); if (IndexMode) { Header.ShxLength = ShapeIndices.Count * 4 + 50; Header.FileLength = ShapeIndices.Count * wordSize + 50; } else { Header.ShxLength = Features.Count * 4 + 50; Header.FileLength = Features.Count * wordSize + 50; } Header.SaveAs(fileName); var shpStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.None, 1000000); var shxStream = new FileStream(Header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 1000000); // Special slightly faster writing for index mode if (IndexMode) { for (int shp = 0; shp < ShapeIndices.Count; shp++) { shpStream.WriteBe(shp + 1); shpStream.WriteBe(wordSize - 4); // shape word size without 4 shapeHeader words. shxStream.WriteBe(50 + shp * wordSize); shxStream.WriteBe(wordSize - 4); shpStream.WriteLe((int)Header.ShapeType); shpStream.WriteLe(Vertex[shp * 2]); shpStream.WriteLe(Vertex[shp * 2 + 1]); if (Z != null) shpStream.WriteLe(Z[shp]); if (M != null) shpStream.WriteLe(M[shp]); } } else { int fid = 0; foreach (IFeature f in Features) { Coordinate c = f.BasicGeometry.Coordinates[0]; shpStream.WriteBe(fid + 1); shpStream.WriteBe(wordSize - 4); shxStream.WriteBe(50 + fid * wordSize); shxStream.WriteBe(wordSize - 4); shpStream.WriteLe((int)Header.ShapeType); if (Header.ShapeType == ShapeType.NullShape) { continue; } shpStream.WriteLe(c.X); shpStream.WriteLe(c.Y); if (Header.ShapeType == ShapeType.PointZ) { shpStream.WriteLe(c.Z); } if (Header.ShapeType == ShapeType.PointM || Header.ShapeType == ShapeType.PointZ) { shpStream.WriteLe(c.M); } fid++; } } shpStream.Close(); shxStream.Close(); UpdateAttributes(); SaveProjection(); }
/// <summary> /// Saves the shapefile to a different filename, but still as a shapefile. This method does not support saving to /// any other file format. /// </summary> /// <param name="filename">The string filename to save as</param> /// <param name="overwrite">A boolean that is true if the file should be overwritten</param> public override void SaveAs(string filename, bool overwrite) { Filename = filename; string dir = Path.GetDirectoryName(filename); if (!Directory.Exists(dir)) { if (MessageBox.Show("Directory " + dir + " does not exist. Do you want to create it?", "Create Directory?", MessageBoxButtons.YesNo) != DialogResult.OK) return; Directory.CreateDirectory(dir); } InvalidateEnvelope(); Header.Xmin = Envelope.Minimum.X; Header.Xmax = Envelope.Maximum.X; Header.Ymin = Envelope.Minimum.Y; Header.Ymax = Envelope.Maximum.Y; if (CoordinateType == CoordinateTypes.Regular) { Header.ShapeType = ShapeTypes.Point; } if (CoordinateType == CoordinateTypes.M) { Header.ShapeType = ShapeTypes.PointM; } if (CoordinateType == CoordinateTypes.Z) { Header.ShapeType = ShapeTypes.PointZ; } if (Header.ShapeType == ShapeTypes.Point || Header.ShapeType == ShapeTypes.PointM) { // test to see if the coordinates have added z or m values in the first coordinate int numOrdinates = 2; if (!IndexMode) { if (Features.Count > 0) { Coordinate c = Features[0].BasicGeometry.Coordinates[0]; if (!double.IsNaN(c.Z)) numOrdinates = 3; } } else { if (Z != null && Z.Length == ShapeIndices.Count) { numOrdinates = 3; } } if (numOrdinates > 2) { Header.ShapeType = ShapeTypes.PointZ; Header.FileLength = 18 * Features.Count + 50; } } if (Header.ShapeType == ShapeTypes.PointZ) { Header.Zmin = Envelope.Minimum.Z; Header.Zmax = Envelope.Maximum.Z; } if (Header.ShapeType == ShapeTypes.PointM || Header.ShapeType == ShapeTypes.PointZ) { Header.Mmin = Envelope.Minimum.M; Header.Mmax = Envelope.Maximum.M; } if(IndexMode) { Header.ShxLength = ShapeIndices.Count * 4 + 50; } else { Header.ShxLength = Features.Count * 4 + 50; } Header.SaveAs(filename); Stream shpStream = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None, 1000000); Stream shxStream = new FileStream(Header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 1000000); int len = 10; if (Header.ShapeType == ShapeTypes.PointM) len = 14; if (Header.ShapeType == ShapeTypes.PointZ) len = 18; // Special slightly faster writing for index mode if(IndexMode) { for(int shp = 0; shp < ShapeIndices.Count; shp++) { shpStream.WriteBe(shp + 1); shpStream.WriteBe(len); shxStream.WriteBe(50 + shp * (len + 4)); shxStream.WriteBe(len); shpStream.WriteLe((int)Header.ShapeType); shpStream.WriteLe(Vertex[shp*2]); shpStream.WriteLe(Vertex[shp*2+1]); if (Z != null) shpStream.WriteLe(Z[shp]); if (M != null) shpStream.WriteLe(M[shp]); } } else { int fid = 0; foreach (IFeature f in Features) { Coordinate c = f.BasicGeometry.Coordinates[0]; shpStream.WriteBe(fid + 1); shpStream.WriteBe(len); shxStream.WriteBe(50 + fid * (len + 4)); shxStream.WriteBe(len); shpStream.WriteLe((int)Header.ShapeType); if (Header.ShapeType == ShapeTypes.NullShape) { continue; } shpStream.WriteLe(c.X); shpStream.WriteLe(c.Y); if (Header.ShapeType == ShapeTypes.PointZ) { shpStream.WriteLe(c.Z); } if (Header.ShapeType == ShapeTypes.PointM || Header.ShapeType == ShapeTypes.PointZ) { shpStream.WriteLe(c.M); } fid++; } } shpStream.Flush(); shpStream.Close(); shxStream.Flush(); shxStream.Close(); Stopwatch sw = new Stopwatch(); sw.Start(); UpdateAttributes(); sw.Stop(); MessageBox.Show("Attribute handling Time: " + sw.ElapsedMilliseconds); SaveProjection(); }
/// <inheritdocs/> protected override void AppendBasicGeometry(ShapefileHeader header, IBasicGeometry feature, int numFeatures) { FileInfo fi = new FileInfo(Filename); int offset = Convert.ToInt32(fi.Length / 2); FileStream shpStream = new FileStream(Filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000); FileStream shxStream = new FileStream(header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 100); Coordinate point = feature.Coordinates[0]; int contentLength = 6; if (header.ShapeType == ShapeType.PointM) { contentLength += 4; // one additional value (m) } if (header.ShapeType == ShapeType.PointZ) { contentLength += 8; // 2 additional values (m, z) } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shxStream.Flush(); shxStream.Close(); // X Y Points // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(numFeatures); // Byte 0 Record Number Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shpStream.WriteLe((int)header.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (header.ShapeType == ShapeType.NullShape) { return; } shpStream.WriteLe(point.X); // Byte 12 X Double 1 Little shpStream.WriteLe(point.Y); // Byte 20 Y Double 1 Little if (header.ShapeType == ShapeType.PointM) { shpStream.WriteLe(point.M); // Byte 28 M Double 1 Little } else if (header.ShapeType == ShapeType.PointZ) { shpStream.WriteLe(point.Z); // Byte 28 Z Double 1 Little shpStream.WriteLe(point.M); // Byte 36 M Double 1 Little } shpStream.Flush(); shpStream.Close(); offset += contentLength; Shapefile.WriteFileLength(Filename, offset); Shapefile.WriteFileLength(header.ShxFilename, 50 + numFeatures * 4); }
protected override void WriteFeatures(string fileName) { // Set Header.ShapeType before setting extent. switch (CoordinateType) { case CoordinateType.Regular: Header.ShapeType = ShapeType.MultiPoint; break; case CoordinateType.M: Header.ShapeType = ShapeType.MultiPointM; break; case CoordinateType.Z: Header.ShapeType = ShapeType.MultiPointZ; break; default: throw new Exception("Unsupported CoordinateType"); } // Calculate total .shp file length var totalOffset = 50; for (var shp = 0; shp < Count; shp++) { var f = GetFeature(shp); totalOffset += GetContentLength(f); } // Save headers for .shp and .shx files InvalidateEnvelope(); Header.SetExtent(Extent); Header.ShxLength = 50 + Count * 4; Header.FileLength = totalOffset; Header.SaveAs(fileName); // Reset shapeheaders ResetShapeHeaders(); // Append data into .shp and .shx int offset = 50; using (var shpStream = new FileStream(Header.Filename, FileMode.Append)) using (var shxStream = new FileStream(Header.ShxFilename, FileMode.Append)) { for (var shp = 0; shp < Count; shp++) { shpStream.WriteBe(shp + 1); var feature = GetFeature(shp); var shpt = feature.ShapeType.GetValueOrDefault(Header.ShapeType); var contentLen = GetContentLength(feature); shpStream.WriteBe(contentLen - 4); shpStream.WriteLe((int)shpt); if (shpt != ShapeType.NullShape) { // Bounding Box var extent = feature.Envelope.ToExtent(); shpStream.WriteLe(extent.MinX); shpStream.WriteLe(extent.MinY); shpStream.WriteLe(extent.MaxX); shpStream.WriteLe(extent.MaxY); // NumPoints shpStream.WriteLe(feature.NumPoints); // XY coordinates for (int i = 0; i < feature.NumPoints; i++) { shpStream.WriteLe(feature.Coordinates[i].X); shpStream.WriteLe(feature.Coordinates[i].Y); } // Z coordinates if (shpt == ShapeType.MultiPointZ) { // Z-box var minZ = feature.Coordinates.Min(_ => _.Z); var maxZ = feature.Coordinates.Max(_ => _.Z); shpStream.WriteLe(minZ); shpStream.WriteLe(maxZ); // Z coordinates for (var i = 0; i < feature.NumPoints; i++) { shpStream.WriteLe(feature.Coordinates[i].Z); } } // M coordinates if (shpt == ShapeType.MultiPointZ || shpt == ShapeType.MultiPointM) { // M-box var minm = feature.Coordinates.Min(_ => _.M); var maxm = feature.Coordinates.Max(_ => _.M); shpStream.WriteLe(minm); shpStream.WriteLe(maxm); // M coordinates for (var i = 0; i < feature.NumPoints; i++) { shpStream.WriteLe(feature.Coordinates[i].M); } } } shxStream.WriteBe(offset); shxStream.WriteBe(contentLen - 4); offset += contentLen; } } }
private void SaveAsIndexed(string fileName) { var shpStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); var shxStream = new FileStream(Header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); int fid = 0; int offset = 50; // the shapefile header starts at 100 bytes, so the initial offset is 50 words int contentLength = 0; foreach (ShapeRange shape in ShapeIndices) { offset += contentLength; // adding the previous content length from each loop calculates the word offset contentLength = 20; if (Header.ShapeType == ShapeType.MultiPoint) { contentLength += shape.NumPoints * 8; } if (Header.ShapeType == ShapeType.MultiPointM) { contentLength += 8; // mmin, mmax contentLength += shape.NumPoints * 12; } if (Header.ShapeType == ShapeType.MultiPointZ) { contentLength += 16; // mmin, mmax, zmin, zmax contentLength += shape.NumPoints * 16; } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Length Integer 1 Big // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(fid + 1); // Byte 0 Record Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Length Integer 1 Big shpStream.WriteLe((int)Header.ShapeType); // Byte 8 Type 3 Integer 1 Little if (Header.ShapeType == ShapeType.NullShape) { continue; } shpStream.WriteLe(shape.Extent.MinX); // Byte 12 Xmin Double 1 Little shpStream.WriteLe(shape.Extent.MinY); // Byte 20 Ymin Double 1 Little shpStream.WriteLe(shape.Extent.MaxX); // Byte 28 Xmax Double 1 Little shpStream.WriteLe(shape.Extent.MaxY); // Byte 36 Ymax Double 1 Little shpStream.WriteLe(shape.NumPoints); // Byte 44 #Points Integer 1 Little int start = shape.StartIndex; int count = shape.NumPoints; shpStream.WriteLe(Vertex, start * 2, count * 2); if (Header.ShapeType == ShapeType.MultiPointZ) { double[] shapeZ = new double[count]; Array.Copy(Z, start, shapeZ, 0, count); shpStream.WriteLe(shapeZ.Min()); shpStream.WriteLe(shapeZ.Max()); shpStream.WriteLe(Z, start, count); } if (Header.ShapeType == ShapeType.MultiPointM || Header.ShapeType == ShapeType.MultiPointZ) { if (M != null && M.Length >= start + count) { double[] shapeM = new double[count]; Array.Copy(M, start, shapeM, 0, count); shpStream.WriteLe(shapeM.Min()); shpStream.WriteLe(shapeM.Max()); shpStream.WriteLe(M, start, count); } } fid++; offset += 4; } shpStream.Close(); shxStream.Close(); offset += contentLength; WriteFileLength(Filename, offset); UpdateAttributes(); SaveProjection(); }
/// <summary> /// Writes the current content to the specified file. /// </summary> /// <param name="header">The header to write</param> /// <param name="fileName">Basically the same code can be used for the shp and shx files</param> /// <param name="numShapes">The integer number of shapes to write to the file</param> private static void WriteHeader(ShapefileHeader header, string fileName, int numShapes) { string dir = Path.GetDirectoryName(fileName); if (dir != null) { if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } FileStream bbWriter = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None, 100); bbWriter.WriteBe(header.FileCode); // Byte 0 File Code 9994 Integer Big byte[] bt = new byte[20]; bbWriter.Write(bt, 0, 20); // Bytes 4 - 20 are unused // This is overwritten later bbWriter.WriteBe(50 + 4 * numShapes); // Byte 24 File Length File Length Integer Big bbWriter.WriteLe(header.Version); // Byte 28 Version 1000 Integer Little bbWriter.WriteLe((int)header.ShapeType); // Byte 32 Shape Type Shape Type Integer Little bbWriter.WriteLe(header.Xmin); // Byte 36 Bounding Box Xmin Double Little bbWriter.WriteLe(header.Ymin); // Byte 44 Bounding Box Ymin Double Little bbWriter.WriteLe(header.Xmax); // Byte 52 Bounding Box Xmax Double Little bbWriter.WriteLe(header.Ymax); // Byte 60 Bounding Box Ymax Double Little bbWriter.WriteLe(header.Zmin); // Byte 68 Bounding Box Zmin Double Little bbWriter.WriteLe(header.Zmax); // Byte 76 Bounding Box Zmax Double Little bbWriter.WriteLe(header.Mmin); // Byte 84 Bounding Box Mmin Double Little bbWriter.WriteLe(header.Mmax); // Byte 92 Bounding Box Mmax Double Little // ------------ WRITE TO SHP FILE ------------------------- bbWriter.Close(); }
/// <summary> /// Saves the file to a new location /// </summary> /// <param name="fileName">The fileName to save</param> /// <param name="overwrite">Boolean that specifies whether or not to overwrite the existing file</param> private void SaveAsIndexed(string fileName, bool overwrite) { Filename = fileName; string dir = Path.GetDirectoryName(fileName); if (dir != null && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } if (File.Exists(fileName)) { if (fileName != Filename && overwrite == false) throw new IOException("File exists."); File.Delete(fileName); string shx = Path.ChangeExtension(fileName, ".shx"); if (File.Exists(shx)) File.Delete(shx); } // comment out by keen edge as per this discussion // http://dotspatial.codeplex.com/Thread/View.aspx?ThreadId=234754 // InvalidateEnvelope(); if (CoordinateType == CoordinateType.Regular) { Header.ShapeType = ShapeType.PolyLine; } if (CoordinateType == CoordinateType.M) { Header.ShapeType = ShapeType.PolyLineM; } if (CoordinateType == CoordinateType.Z) { Header.ShapeType = ShapeType.PolyLineZ; } // Set Header.ShapeType before calling SetExtent. Header.SetExtent(MyExtent); Header.ShxLength = ShapeIndices.Count * 4 + 50; Header.SaveAs(fileName); FileStream shpStream = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); FileStream shxStream = new FileStream(Header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); int fid = 0; int offset = 50; // the shapefile header starts at 100 bytes, so the initial offset is 50 words int contentLength = 0; foreach (ShapeRange shape in ShapeIndices) { offset += contentLength; // adding the previous content length from each loop calculates the word offset contentLength = 22; contentLength += 2 * shape.Parts.Count; if (Header.ShapeType == ShapeType.PolyLine) { contentLength += shape.NumPoints * 8; // x, y } if (Header.ShapeType == ShapeType.PolyLineM) { contentLength += 8; // mmin mmax contentLength += shape.NumPoints * 12; // x, y, m } if (Header.ShapeType == ShapeType.PolyLineZ) { contentLength += 16; // mmin, mmax, zmin, zmax contentLength += shape.NumPoints * 16; // x, y, z, m } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(fid + 1); // Byte 0 Record Number Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shpStream.WriteLe((int)Header.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (Header.ShapeType == ShapeType.NullShape) { continue; } shpStream.WriteLe(shape.Extent.MinX); // Byte 12 Xmin Double 1 Little shpStream.WriteLe(shape.Extent.MinY); // Byte 20 Ymin Double 1 Little shpStream.WriteLe(shape.Extent.MaxX); // Byte 28 Xmax Double 1 Little shpStream.WriteLe(shape.Extent.MaxY); // Byte 36 Ymax Double 1 Little shpStream.WriteLe(shape.NumParts); // Byte 44 NumParts Integer 1 Little shpStream.WriteLe(shape.NumPoints); // Byte 48 NumPoints Integer 1 Little // Byte 52 Parts Integer NumParts Little foreach (PartRange part in shape.Parts) { shpStream.WriteLe(part.PartOffset); } int start = shape.StartIndex; int count = shape.NumPoints; shpStream.WriteLe(Vertex, start * 2, count * 2); // Byte X Points Point NumPoints Little if (Header.ShapeType == ShapeType.PolyLineZ) { double[] shapeZ = new double[count]; Array.Copy(Z, start, shapeZ, 0, count); shpStream.WriteLe(shapeZ.Min()); shpStream.WriteLe(shapeZ.Max()); shpStream.WriteLe(Z, start, count); } if (Header.ShapeType == ShapeType.PolyLineM || Header.ShapeType == ShapeType.PolyLineZ) { if (M != null && M.Length >= start + count) { double[] shapeM = new double[count]; Array.Copy(M, start, shapeM, 0, count); shpStream.WriteLe(shapeM.Min()); shpStream.WriteLe(shapeM.Max()); shpStream.WriteLe(M, start, count); } } fid++; offset += 4; // header bytes } shpStream.Flush(); shxStream.Flush(); shpStream.Close(); shxStream.Close(); offset += contentLength; //offset += 4; WriteFileLength(Filename, offset); WriteFileLength(Header.ShxFilename, 50 + fid * 4); UpdateAttributes(); SaveProjection(); }
protected override void WriteFeatures(string fileName) { // Set Header.ShapeType before setting extent. switch (CoordinateType) { case CoordinateType.Regular: Header.ShapeType = FeatureType == FeatureType.Line ? ShapeType.PolyLine : ShapeType.Polygon; break; case CoordinateType.M: Header.ShapeType = FeatureType == FeatureType.Line ? ShapeType.PolyLineM : ShapeType.PolygonM; break; case CoordinateType.Z: Header.ShapeType = FeatureType == FeatureType.Line ? ShapeType.PolyLineZ : ShapeType.PolygonZ; break; default: throw new Exception("Unsupported CoordinateType"); } // Calculate total .shp file length var totalOffset = 50; for (var shp = 0; shp < Count; shp++) { var f = GetFeature(shp); totalOffset += GetContentLength(f); } // Save headers for .shp and .shx files InvalidateEnvelope(); Header.SetExtent(Extent); Header.ShxLength = 50 + Count * 4; Header.FileLength = totalOffset; Header.SaveAs(fileName); // Reset shapeheaders ResetShapeHeaders(); // Append data into .shp and .shx int offset = 50; using (var shpStream = new FileStream(Header.Filename, FileMode.Append)) using (var shxStream = new FileStream(Header.ShxFilename, FileMode.Append)) { for (var shp = 0; shp < Count; shp++) { shpStream.WriteBe(shp + 1); var feature = GetFeature(shp); var shpt = feature.ShapeType.GetValueOrDefault(Header.ShapeType); var contentLen = GetContentLength(feature); shpStream.WriteBe(contentLen - 4); shpStream.WriteLe((int)shpt); if (shpt != ShapeType.NullShape) { // Bounding Box var extent = feature.Envelope.ToExtent(); shpStream.WriteLe(extent.MinX); shpStream.WriteLe(extent.MinY); shpStream.WriteLe(extent.MaxX); shpStream.WriteLe(extent.MaxY); // NumParts shpStream.WriteLe(feature.NumGeometries); // NumPoints shpStream.WriteLe(feature.NumPoints); // Parts and Points var parts = new int[feature.NumGeometries]; var points = new List<Coordinate>(feature.NumPoints); for (var iPart = 0; iPart < feature.NumGeometries; iPart++) { parts[iPart] = points.Count; var bl = feature.GetBasicGeometryN(iPart); points.AddRange(bl.Coordinates); } // Parts shpStream.WriteLe(parts, 0, parts.Length); // XY coordinates foreach (var t in points) { shpStream.WriteLe(t.X); shpStream.WriteLe(t.Y); } // Z coordinates if (shpt == ShapeType.PolyLineZ || shpt == ShapeType.PolygonZ) { // Z-box var minZ = feature.Coordinates.Min(_ => _.Z); var maxZ = feature.Coordinates.Max(_ => _.Z); shpStream.WriteLe(minZ); shpStream.WriteLe(maxZ); // Z coordinates for (var i = 0; i < feature.NumPoints; i++) { shpStream.WriteLe(feature.Coordinates[i].Z); } } // M coordinates if (shpt == ShapeType.PolyLineZ || shpt == ShapeType.PolygonZ || shpt == ShapeType.PolyLineM || shpt == ShapeType.PolygonM) { // M-box var minm = feature.Coordinates.Min(_ => _.M); var maxm = feature.Coordinates.Max(_ => _.M); shpStream.WriteLe(minm); shpStream.WriteLe(maxm); // M coordinates for (var i = 0; i < feature.NumPoints; i++) { shpStream.WriteLe(feature.Coordinates[i].M); } } } shxStream.WriteBe(offset); shxStream.WriteBe(contentLen - 4); offset += contentLen; } } }
/// <summary> /// Saves the file to a new location /// </summary> /// <param name="filename">The filename to save</param> /// <param name="overwrite">Boolean that specifies whether or not to overwrite the existing file</param> private void SaveAsIndexed(string filename, bool overwrite) { if (File.Exists(filename) && filename != Filename && overwrite == false) { if (MessageBox.Show("The file already exists. Do you wish to overwrite it?", "File Exists", MessageBoxButtons.YesNo) == DialogResult.No) return; File.Delete(filename); } string dir = Path.GetDirectoryName(filename); if (!Directory.Exists(dir)) { if (MessageBox.Show("Directory " + dir + " does not exist. Do you want to create it?", "Create Directory?", MessageBoxButtons.YesNo) != DialogResult.OK) return; Directory.CreateDirectory(dir); } Header.Xmin = Envelope.Minimum.X; Header.Xmax = Envelope.Maximum.X; Header.Ymin = Envelope.Minimum.Y; Header.Ymax = Envelope.Maximum.Y; if (CoordinateType == CoordinateTypes.Regular) { Header.ShapeType = ShapeTypes.MultiPoint; } if (CoordinateType == CoordinateTypes.M) { Header.ShapeType = ShapeTypes.MultiPointM; } if (CoordinateType == CoordinateTypes.Z) { Header.ShapeType = ShapeTypes.MultiPointZ; } if (Header.ShapeType == ShapeTypes.PolygonZ) { Header.Zmin = Z.Min(); Header.Zmax = Z.Max(); } if (Header.ShapeType == ShapeTypes.PolygonM || Header.ShapeType == ShapeTypes.PolygonZ) { Header.Mmin = M.Min(); Header.Mmax = M.Max(); } Header.ShxLength = ShapeIndices.Count * 4 + 50; Header.SaveAs(filename); FileStream shpStream = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); FileStream shxStream = new FileStream(Header.ShxFilename, FileMode.Append, FileAccess.Write, FileShare.None, 10000000); int fid = 0; int offset = 50; // the shapefile header starts at 100 bytes, so the initial offset is 50 words int contentLength = 0; foreach (ShapeRange shape in ShapeIndices) { offset += contentLength; // adding the previous content length from each loop calculates the word offset contentLength = 20; if (Header.ShapeType == ShapeTypes.MultiPoint) { contentLength += shape.NumPoints * 8; } if (Header.ShapeType == ShapeTypes.MultiPointM) { contentLength += 8; // mmin, mmax contentLength += shape.NumPoints * 12; } if (Header.ShapeType == ShapeTypes.MultiPointZ) { contentLength += 16; // mmin, mmax, zmin, zmax contentLength += shape.NumPoints * 16; } // Index File // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shxStream.WriteBe(offset); // Byte 0 Offset Integer 1 Big shxStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big // X Y Poly Lines // --------------------------------------------------------- // Position Value Type Number Byte Order // --------------------------------------------------------- shpStream.WriteBe(fid + 1); // Byte 0 Record Number Integer 1 Big shpStream.WriteBe(contentLength); // Byte 4 Content Length Integer 1 Big shpStream.WriteLe((int)Header.ShapeType); // Byte 8 Shape Type 3 Integer 1 Little if (Header.ShapeType == ShapeTypes.NullShape) { continue; } shpStream.WriteLe(shape.Extent.XMin); // Byte 12 Xmin Double 1 Little shpStream.WriteLe(shape.Extent.YMin); // Byte 20 Ymin Double 1 Little shpStream.WriteLe(shape.Extent.XMax); // Byte 28 Xmax Double 1 Little shpStream.WriteLe(shape.Extent.YMax); // Byte 36 Ymax Double 1 Little shpStream.WriteLe(shape.NumPoints); // Byte 44 NumPoints Integer 1 Little int start = shape.StartIndex; int count = shape.NumPoints; shpStream.WriteLe(Vertex, start * 2, count * 2); // Byte X Points Point NumPoints Little if (Header.ShapeType == ShapeTypes.MultiPointZ) { double[] shapeZ = new double[count]; Array.Copy(Z, start, shapeZ, 0, count); shpStream.WriteLe(shapeZ.Min()); shpStream.WriteLe(shapeZ.Max()); shpStream.WriteLe(Z, start, count); } if (Header.ShapeType == ShapeTypes.MultiPointM || Header.ShapeType == ShapeTypes.MultiPointZ) { if (M != null && M.Length >= start + count) { double[] shapeM = new double[count]; Array.Copy(M, start, shapeM, 0, count); shpStream.WriteLe(shapeM.Min()); shpStream.WriteLe(shapeM.Max()); shpStream.WriteLe(M, start, count); } } fid++; offset += 4; } shpStream.Flush(); shxStream.Flush(); shpStream.Close(); shxStream.Close(); offset += contentLength; WriteFileLength(Filename, offset); UpdateAttributes(); SaveProjection(); }
protected override void WriteFeatures(string fileName) { // Set Header.ShapeType before setting extent. // wordSize is the length of the byte representation in 16 bit words of a single shape, including header. int wordSize; switch (CoordinateType) { case CoordinateType.Regular: Header.ShapeType = ShapeType.Point; wordSize = 14; // 3 int(2) and 2 double(4) = X,Y break; case CoordinateType.M: Header.ShapeType = ShapeType.PointM; wordSize = 18; // 3 int(2), 3 double(4) = X,Y,M break; case CoordinateType.Z: Header.ShapeType = ShapeType.PointZ; wordSize = 22; // 3 int(2), 4 double (4) = X,Y,Z,M break; default: throw new Exception("Unsupported CoordinateType"); } // Calculate total .shp file length var totalOffset = 50; for (var shp = 0; shp < Count; shp++) { var f = GetFeature(shp); var shpt = f.ShapeType.GetValueOrDefault(Header.ShapeType); totalOffset += shpt == ShapeType.NullShape ? 6 : wordSize; } // Save headers for .shp and .shx files InvalidateEnvelope(); Header.SetExtent(Extent); Header.ShxLength = 50 + Count * 4; Header.FileLength = totalOffset; Header.SaveAs(fileName); // Reset shapeheaders ResetShapeHeaders(); // Append data into .shp and .shx int offset = 50; using (var shpStream = new FileStream(Header.Filename, FileMode.Append)) using (var shxStream = new FileStream(Header.ShxFilename, FileMode.Append)) { for (var shp = 0; shp < Count; shp++) { shpStream.WriteBe(shp + 1); var feature = GetFeature(shp); var shpt = feature.ShapeType.GetValueOrDefault(Header.ShapeType); var contentLen = shpt == ShapeType.NullShape ? 2 : wordSize - 4; shpStream.WriteBe(contentLen); shpStream.WriteLe((int)shpt); if (shpt != ShapeType.NullShape) { var coordinate = feature.Coordinates[0]; shpStream.WriteLe(coordinate.X); shpStream.WriteLe(coordinate.Y); if (shpt == ShapeType.PointZ) shpStream.WriteLe(coordinate.Z); if (shpt == ShapeType.PointZ || shpt == ShapeType.PointM) shpStream.WriteLe(coordinate.M); } shxStream.WriteBe(offset); shxStream.WriteBe(contentLen); offset += shpt == ShapeType.NullShape ? 6 : wordSize; } } }
/// <summary> /// Writes the current content to the specified file. /// </summary> /// <param name="destFilename">The string fileName to write to</param> /// <param name="destFileLength">The only difference between the shp header and the /// shx header is the file length parameter.</param> private void Write(string destFilename, int destFileLength) { var dir = Path.GetDirectoryName(Path.GetFullPath(Filename)); if (dir != null && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } using (var fs = new FileStream(destFilename, FileMode.Create)) { fs.WriteBe(FileCode); // Byte 0 File Code 9994 Integer Big var bt = new byte[20]; fs.Write(bt, 0, 20); // Bytes 4 - 20 are unused fs.WriteBe(destFileLength); // Byte 24 File Length File Length Integer Big fs.WriteLe(Version); // Byte 28 Version 1000 Integer Little fs.WriteLe((int) ShapeType); // Byte 32 Shape Type Shape Type Integer Little fs.WriteLe(Xmin); // Byte 36 Bounding Box Xmin Double Little fs.WriteLe(Ymin); // Byte 44 Bounding Box Ymin Double Little fs.WriteLe(Xmax); // Byte 52 Bounding Box Xmax Double Little fs.WriteLe(Ymax); // Byte 60 Bounding Box Ymax Double Little fs.WriteLe(Zmin); // Byte 68 Bounding Box Zmin Double Little fs.WriteLe(Zmax); // Byte 76 Bounding Box Zmax Double Little fs.WriteLe(Mmin); // Byte 84 Bounding Box Mmin Double Little fs.WriteLe(Mmax); // Byte 92 Bounding Box Mmax Double Little } }