/// <summary> /// Writes the specified feature collection. /// </summary> /// <param name="featureCollection">The feature collection.</param> public void Write(IEnumerable <IFeature> featureCollection) { // Test if the Header is initialized if (Header is null) { throw new ApplicationException("Header must be set first!"); } using (var featuresEnumerator = featureCollection.GetEnumerator()) { // scan the original sequence looking for a geometry that we can // use to figure out the shape type. keep the original features // around so we don't have to loop through the input twice; we // shouldn't have to look *too* far for a non-empty geometry. Geometry representativeGeometry = null; var headFeatures = new List <IFeature>(); while (representativeGeometry?.IsEmpty != false && featuresEnumerator.MoveNext()) { var feature = featuresEnumerator.Current; headFeatures.Add(feature); representativeGeometry = feature.Geometry; } var shapeFileType = Shapefile.GetShapeType(representativeGeometry); using (_dbaseWriter) using (var shapefileWriter = new ShapefileWriter(_geometryFactory, _streamProviderRegistry, shapeFileType)) { _dbaseWriter.Write(Header); string[] fieldNames = Array.ConvertAll(Header.Fields, field => field.Name); object[] values = new object[fieldNames.Length]; // first, write the one(s) that we scanned already. foreach (var feature in headFeatures) { Write(feature); } // now continue through the features we haven't scanned yet. while (featuresEnumerator.MoveNext()) { Write(featuresEnumerator.Current); } void Write(IFeature feature) { shapefileWriter.Write(feature.Geometry); var attribs = feature.Attributes; for (int i = 0; i < fieldNames.Length; i++) { values[i] = attribs[fieldNames[i]]; } _dbaseWriter.Write(values); } } } }
public static void WriteGeometryCollection(IStreamProviderRegistry streamProviderRegistry, GeometryCollection geometryCollection, bool createDummyDbf = true) { var shapeFileType = Shapefile.GetShapeType(geometryCollection); using (var writer = new ShapefileWriter(geometryCollection.Factory, streamProviderRegistry, shapeFileType)) { var dbfWriter = createDummyDbf ? new DbaseFileWriter(streamProviderRegistry) : null; WriteGeometryCollection(writer, dbfWriter, geometryCollection, createDummyDbf); if (dbfWriter != null) { dbfWriter.Dispose(); } } }
/// <summary> /// Method to write a collection of geometries to a shapefile on disk. /// </summary> /// <remarks> /// Assumes the type given for the first geometry is the same for all subsequent geometries. /// For example, is, if the first Geometry is a Multi-polygon/ Polygon, the subsequent geometies are /// Muli-polygon/ polygon and not lines or points. /// The dbase file for the corresponding shapefile contains one column called row. It contains /// the row number. /// </remarks> /// <param name="filename">The filename to write to (minus the .shp extension).</param> /// <param name="geometryCollection">The GeometryCollection to write.</param> public static void WriteGeometryCollection(string filename, IGeometryCollection geometryCollection) { var shapeFileType = Shapefile.GetShapeType(geometryCollection); var numShapes = geometryCollection.NumGeometries; using (var writer = new ShapefileWriter(geometryCollection.Factory, filename, shapeFileType)) { for (var i = 0; i < numShapes; i++) { writer.Write(geometryCollection[i]); } } WriteDummyDbf(filename + ".dbf", numShapes); }
/// <summary> /// Writes a shapefile to disk. /// </summary> /// <remarks> /// Assumes the type given for the first geometry is the same for all subsequent geometries. /// For example, is, if the first Geometry is a Multi-polygon/ Polygon, the subsequent geometies are /// Muli-polygon/ polygon and not lines or points. /// The dbase file for the corresponding shapefile contains one column called row. It contains /// the row number. /// </remarks> /// <param name="filename">The filename to write to (minus the .shp extension).</param> /// <param name="geometryCollection">The GeometryCollection to write.</param> public void Write(IGeometryCollection geometryCollection) { //FileStream shpStream = new FileStream(filename + ".shp", FileMode.Create); //FileStream shxStream = new FileStream(filename + ".shx", FileMode.Create); shpStream = new MemoryStream(); shxStream = new MemoryStream(); BigEndianBinaryWriter shpBinaryWriter = new BigEndianBinaryWriter(shpStream); BigEndianBinaryWriter shxBinaryWriter = new BigEndianBinaryWriter(shxStream); // assumes ShapeHandler handler = Shapefile.GetShapeHandler(Shapefile.GetShapeType(geometryCollection.Geometries[0])); IGeometry body; int numShapes = geometryCollection.NumGeometries; // calc the length of the shp file, so it can put in the header. int shpLength = 50; for (int i = 0; i < numShapes; i++) { body = (IGeometry)geometryCollection.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 Envelope env = geometryCollection.EnvelopeInternal as Envelope; Envelope bounds = ShapeHandler.GetEnvelopeExternal(geometryFactory.PrecisionModel, env); shpHeader.Bounds = bounds; // assumes Geometry type of the first item will the same for all other items // in the collection. shpHeader.ShapeType = Shapefile.GetShapeType(geometryCollection.Geometries[0]); shpHeader.Write(shpBinaryWriter); // write the .shx header ShapefileHeader shxHeader = new ShapefileHeader(); shxHeader.FileLength = shxLength; shxHeader.Bounds = shpHeader.Bounds; // assumes Geometry type of the first item will the same for all other items in the collection. shxHeader.ShapeType = Shapefile.GetShapeType(geometryCollection.Geometries[0]); shxHeader.Write(shxBinaryWriter); // write the individual records. int _pos = 50; // header length in WORDS for (int i = 0; i < numShapes; i++) { body = geometryCollection.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(); //shxStream.Seek(0, SeekOrigin.Begin); ////shxBinaryWriter.Close(); shpBinaryWriter.Flush(); //shpStream.Seek(0, SeekOrigin.Begin); //shpBinaryWriter.Close(); // WriteDummyDbf(filename + ".dbf", numShapes); }