NetTopologySuite / NetTopologySuite.IO.ShapeFile

The ShapeFile IO module for NTS.
35 stars 25 forks source link

Shapefiles in-memory #10

Closed K1ngMX closed 3 months ago

K1ngMX commented 6 years ago

Hello,

is it possible to get the shapefile parts in-memory somehow ? I would like to create the shapefile with all its parts and zip them afterwards, so the user will only download the zip file. Now, it would be useful if I could skip the writing to the harddisk all together. Any idea?

Thanks

K1ngMX commented 6 years ago

Sorry for closing, i thought we had found a solution for this here, but unfortunately it didnt work. Any input would be appreciated. Thanks

airbreather commented 6 years ago

I think you should be able to accomplish what you're looking for by using the overloads that accept a NetTopologySuite.IO.Streams.IStreamProviderRegistry and using NetTopologySuite.IO.Streams.ByteStreamProvider instances for the different streams.

airbreather commented 6 years ago

@K1ngMX did my comment resolve your issue? If not, could you provide more details about what you're trying to do?

Svalhansen commented 4 years ago

@airbreather I assume you suggested something like

var shpStream = new MemoryStream(); var dataStream = new MemoryStream();

        var shpStreamProvider = new ShapefileStreamProviderRegistry(
            new ByteStreamProvider(StreamTypes.Shape, shpStream),
            new ByteStreamProvider(StreamTypes.Data, dataStream));

        var writer = new ShapefileDataWriter(shpStreamProvider, new GeometryFactory(), Encoding.UTF8);
        var outDbaseHeader = ShapefileDataWriter.GetHeader(features[0], features.Count);
        writer.Header = outDbaseHeader;
        writer.Write(features);

This throws an exception like below, so I assume somewhere inside there is an a fixed assignment of a stream buffer size.

System.NotSupportedException : Memory stream is not expandable. at System.IO.MemoryStream.set_Capacity(Int32 value) at System.IO.MemoryStream.EnsureCapacity(Int32 value) at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.BinaryWriter.Write(Int32 value) at NetTopologySuite.IO.ShapefileHeader.Write(BigEndianBinaryWriter file) at NetTopologySuite.IO.ShapefileWriter.WriteShpHeader(BigEndianBinaryWriter shpBinaryWriter, Int32 shpLength, Envelope bounds) at NetTopologySuite.IO.ShapefileWriter..ctor(GeometryFactory geometryFactory, IStreamProviderRegistry streamProviderRegistry, ShapeGeometryType geomType) at NetTopologySuite.IO.ShapefileDataWriter.Write(IEnumerable`1 featureCollection)

Svalhansen commented 4 years ago

Trying to define a fixzed size of the memory stream actually makes the code run but only with encoding set on both header and streem.

The byte array of the stream is empty though. So it seems the overload is not really made for writing?

var shpStream = new MemoryStream(new byte[1000]); var dataStream = new MemoryStream(new byte[1000]);

        var shpStreamProvider = new ShapefileStreamProviderRegistry(
            new ByteStreamProvider(StreamTypes.Shape, shpStream),
            new ByteStreamProvider(StreamTypes.Data, dataStream));

        var writer = new ShapefileDataWriter(shpStreamProvider, new GeometryFactory(),Encoding.UTF8);
        var outDbaseHeader = ShapefileDataWriter.GetHeader(features[0], features.Count, Encoding.UTF8);
        writer.Header = outDbaseHeader;
        writer.Write(features);

        var test = shpStream.ToArray();
CodeBardian commented 3 years ago

it's been some years since this issue was created, but in case anyone stumbles across it just like I recently did... I wrote a comment on this other issue how I resolved writing a shapefile in memory: https://github.com/NetTopologySuite/NetTopologySuite.IO.ShapeFile/issues/55#issuecomment-814779655

KubaSzostak commented 3 months ago

Support for a custom-managed stream, which allows shapes to be written to it, has been added in the successor library. There is also a sample code demonstrating how to use streams.