NetTopologySuite / NetTopologySuite.IO.Esri

BSD 3-Clause "New" or "Revised" License
31 stars 16 forks source link

The projection stream is closed. Please leave all streams open. #48

Closed FrankHileman closed 2 weeks ago

FrankHileman commented 1 month ago

Hello, in testing the stream enhancements, I found a problem. Unlike the other streams, which are left open, the projection stream is closed. We should leave all streams open after the write operation. The problem is the use of a using statement, and a StreamWriter constructor. The StreamWriter constructor has a parameter called "leaveOpen", when set to true, will leave the stream open when the StreamWriter is disposed. We should set this to true.


       internal ShapefileWriter(Stream shpStream, Stream shxStream, Stream dbfStream, Stream prjStream, ShapefileWriterOptions options)
           : base(new DbfWriter(dbfStream, options?.Fields, options?.Encoding))
       {
           try
           {
               options = options ?? throw new ArgumentNullException(nameof(options));
               ShapeType = options.ShapeType;
               ShpWriter = CreateShpWriter(shpStream, shxStream);

               if (!string.IsNullOrWhiteSpace(options.Projection) && prjStream != null)
               {
                   using (var writer = new StreamWriter(prjStream))
                   {
                       writer.Write(options.Projection);
                   }
               }
           }
           catch
           {
               DisposeManagedResources();
               throw;
           }
       }

Originally posted by @FrankHileman in https://github.com/NetTopologySuite/NetTopologySuite.IO.Esri/issues/36#issuecomment-2155184426

FrankHileman commented 1 month ago

The fixed code: using (var writer = new StreamWriter(prjStream, Encoding.UTF8, 1024, true)) { writer.Write(options.Projection); }

FrankHileman commented 1 week ago

I have discovered another problem with the stream fix. The default encoding, Encoding.UTF8, writes a byte order mark (BOM) to the projection stream. This should be valid, but my colleague found that ARC-GIS, at least the version they are using, does not accept a BOM in a projection file. In this case, it refuses to read the file, and it ends up with no projection for the shapefile. Subsequently, the shapefile shows up at the wrong location on the earth. While this is a bug in the application, to be safe, we should use the following as the default encoding:new UTF8Encoding(false)

From the MSDN documentation for Encoding.UTF8: "The UTF8Encoding object that is returned by this property might not have the appropriate behavior for your app. It returns a UTF8Encoding object that provides a Unicode byte order mark (BOM). To instantiate a UTF8 encoding that doesn't provide a BOM, call any overload of the UTF8Encoding constructor."

FrankHileman commented 1 week ago

I cannot test this myself (arcgis), so maybe someone else can confirm if there is any way to fix the arcgis behavior instead?

FrankHileman commented 2 days ago

Please see issue #53 .