The ShapeFile IO module for NTS.
The development of this project has been discontinued. Please consider NetTopologySuite.IO.Esri as a replacement.
The ShapeFile IO module for NTS.
The ShapeFile IO module for NTS.
The development of this project has been discontinued. Please consider NetTopologySuite.IO.Esri as a replacement.
question 1:
var reader= new DbaseFileReader(file,encoding);
throw an error and that the object not instance ;
question 2:
for example code;
while (reader.Read())
{
var f = new Feature() { Geometry = reader.Geometry };
f.Attributes = new AttributesTable();
int num = reader.DbaseHeader.NumFields;
for (int i = 0; i < num; ++i)
{
_name = reader.DbaseHeader.Fields[i].Name;
object val = reader.GetValue(i+1);//here is bug,attrbiute table not match column name index
}
};
question 3:
ShapefileDataWriter can't setting default encoding
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
i want to read a shapefile but file not existing ?
ShapeDataReader reader = new ShapeDataReader("mapsuiSample.MURS.shp");
var mbr = reader.ShapefileBounds;
var result = reader.ReadByMBRFilter(mbr);
var coll = result.GetEnumerator();
while (coll.MoveNext())
var item = coll.Current;
From @xivk on February 28, 2017 9:32
I'm working on a tool for a client of mine converting OSM data into a shapefile that can easily consumed for routing and analytics.
Basically I have 2 steps:
Now Itinero can handle the entire world, the planet OSM file, and build a database for the entire world. I don't think it's even possible to attempt writing this to a shapefile but I am having performance issues, for example for a country like germany it takes about 10 hours (!) to write a shapefile with all german roads. Doing this in Itinero-only takes about 30 mins.
I have checked and the bottleneck clearly is the shapefile writer.
So I'm wondering, is it possible to improve the performance of writing a shapefile? Can anyone give me some pointers on where to get started? For example, why does it iterate twice over the source? Any way to compress the result? Germany now give me a shapefile of 70GB (!).
I'm more than willing to contribute the improvements to NTS as usual, but any help getting started would be appreciated.
Copied from original issue: NetTopologySuite/NetTopologySuite#154
Following from #42, we should probably just redo all the shapefile reading code.
It would be nice not to use any of the code from the other library so that we can provide a library that's licensed under BSD-3-clause instead of LGPL.
Hello NetTopologySuite-Team,
I got a question about reading Shapefiles (.shp) with NetTopologySuite.IO.
Is there any way to set the Encoding for the file to be read? All the Shapefiles I get are encoded using Windows-1252. But because I'm using DotNetCore it tries to encode every file as UTF-8 which is problematic with any special characters like ß, ü, ä, ö and so on which just return a "?" as a character instead.
Can someone please provide me with an example of how to read a shp File encoded in Windows-1252 correctly?
I don't need to write any changes to the Shapefile just read the data in the correcly encoded format.
I've attached a Shapefile where this problem occurs.
SCHLAG.zip
From @laetitiamh on September 7, 2016 14:58
Hi!
I am trying to open a shapefile that contains building outlines using NetTopologySuite.IO.ShapefileReader.
I only get around 700 of the 5000+ buildings as a result as the reading stops early because of a faulty linear ring "Number of points must be 0 or >3". This shapefile is automatically generated and contains some errors. I can open the same file in a tool like http://mapshaper.org/ and I can see all the outlines.
The ShapefileEnumerator::MoveNext will return false when it encounters such an exception and as a result the ShapeFileReader::ReadAll will abort the foreach loop.
Could we specifiy as an option to the ShapefileReader to continue reading until the end of the file even when it finds faulty geometries?
Thank you very much!
Copied from original issue: NetTopologySuite/NetTopologySuite#121
Hello, Thanks for open sourcing this library.
I've been trying to open a shapefile in memory via ShapefileStreamProviderRegistry
. The shapefile has .prj file, but the resultant ShapefileDataReader
does not seem to have the CRS info present in the projection file. In fact, the Geometry field of the ShapefileDataReader instance is null (opening the shapefile using filepath also created a datareader with null geometry as well).
Browsing through the source code, I'm not able to find a place where ProjectionStream
field of the StreamProviderRegistry
is used, I'm wondering if the projection stream is read when opening the file?
Best,
From @Labbe21 on October 30, 2017 15:35
I have a shape file generated with QGIS as a zip with dbf, prj, shp and shx files within it.
That file decoding is fine with QGIS Tool and https://mygeodata.cloud/converter/
However, ShapefileDataReader is not able to read all columns as expected.
Most of columns are parsed as ""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" with various number of occurences of "\0" while some columns are ok.
There is the file I'm trying to parse: https://ufile.io/p0zl3
I am using the last version of NetTopologySuite.
Could someone please help me with this issue, I'm running out of ideas to fix this problem.
Copied from original issue: NetTopologySuite/NetTopologySuite#202
Hello,
It looks like the NetTopologySuite NuGet package is signed, but this package is not. When trying to read shapefiles, it now throws this exception:
Could not load file or assembly 'NetTopologySuite.IO.ShapeFile.Extended, Version=1.15.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)
Could we have the NuGet package for this library signed?
Thanks!
Ryan
when i write attribute column length more than 254 that string intercepted,can't write over length 254
on the other hand.ShapefileDataWriter About Chinese random encoding error
I am upgrading from an older version of NTS and my code for reading the attribute tables does not work.
I use DbaseFileHeader.Fields to find the field indices and then use ShapeFileDataReader.GetValue(idx) to read the value from the attribute table.
Using the new NTS I'm getting some strange behavior:
Index 0 in DbaseFileHeader.Fields returns the first field in the attribute table (i.e. ObjectId) as expected.
But ShapeFileDataReader.GetValue(0) returns the geometry object, and index 1 returns the ObjectId value.
Is this by design?
GeometryFactory factory = new GeometryFactory(new PrecisionModel(PrecisionModels.Fixed),3006);
var features = new List<Feature>();
using ( ShapefileDataReader shapeFileDataReader = new ShapefileDataReader(shpFilename, factory))
{
ShapefileHeader shpHeader = shapeFileDataReader.ShapeHeader;
DbaseFileHeader header = shapeFileDataReader.DbaseHeader;
while (shapeFileDataReader.Read())
{
Feature feature = new Feature();
AttributesTable attributesTable = new AttributesTable();
IGeometry geometry = (Geometry)shapeFileDataReader.Geometry;
for (int i = 0; i < header.NumFields; i++)
{
DbaseFieldDescriptor fldDescriptor = header.Fields[i];
attributesTable.Add(fldDescriptor.Name, shapeFileDataReader.GetValue(i));
}
feature.Geometry = geometry;
feature.Attributes = attributesTable;
features.Add(feature);
}
shapeFileDataReader.Close();
}
Thanks
Hi guys,
I'm working on a project that has to be able to serialize and deserialize many FeatureCollection
. I'm using the System.Test.Json.JsonSerializer
with the GeoJsonConverterFactory
to do so, but I can't write any ShapeFile
from the deserialized collections. It has something to do with some attibutes getting deserialized as decimal
(they were double
). Or could the deserialized StjFeature
cause the problem? The error occurs while getting the header via ShapeFileDataWriter.GetHeader(features.First(), features.Count)
.
The regular Feature
shows different types compared to the StjFeature
(the pictures show different FeatureCollection
).
I can not read a specific .shp. The ReadNextNonNullShape function of ShapeMBREnumeratorBase returns a negative number for CurrShapeIndex = Reader.ReadInt32BE () - 1; in shape number 11
SHP_ETRS89.zip
Hi! Thank you for the tool, it is very useful.
However, I faced a problem, ShapefileDataWriter
incorrectly handles dots in the provided filename.
The ShapefileDataWriter
documentation says:
<param name="fileName">File path without any extension</param>
So I pass there:
"C:\\TestOutput\\Dr. J.J.P. Oudsingel\\Dr. J.J.P. Oudsingel Surfaces"
However, it produces a file named "Dr. J.J.P.shp"
I believe this is because of calls to Path.ChangeExtension(path, ".shp")
in the ShapefileStreamProviderRegistry
constructor.
If you require a shapefile name without any extension, maybe the better idea would be to replace Path.ChangeExtension(path, ".shp")
to simple path + ".shp"
?
If you'd like, I can make a PR with these changes.
When writing the length of a column in a DbaseFieldHeader you get some strange behavior. The max size of the length in dbase is 1 byte = 254. If we would add a column with a length of 255, this would result into a column with the length of 1. For me it would be logical that in this case the length would be set to its maximum: 254 of 1 byte
open failure when used arcgis platform open shapefile
display graphic scaling ratio inormal (arcgis 10.2.2)
I want get ShapeFile's AttributeTable ,I did it this way
ShapefileDataReader dataReader = new ShapefileDataReader(shapepath, Factory, Encoding.UTF8);
for (int i = 1; i < fieldNames.Length; i++)
{
attributesTable.Add(fieldNames[i], dataReader.GetValue(i));
}
but Why dataReader's depth is 0,result in an empty reference exception to be thrown.My shp can be read in ArcMap.Is My method wrong? What is the general way to read AttributeTable?
support editing shp files?
how to write geometry collection to single shapefile,has multi dbf rows
Hi all
I'm currently try to export wkt poligons to Shapefile, but when i go to write features, like that:
`// Use the dataWriter to write the shape file with geometry and data
ShapefileDataWriter dataWriter = new ShapefileDataWriter(shapeFileName, outGeomFactory, encoding);
// Header
DbaseFileHeader outDbaseHeader = ShapefileDataWriter.GetHeader(features[0], features.Count, encoding);
dataWriter.Header = outDbaseHeader;
// Write feature
dataWriter.Write(features); //Exception is thrown here`
I have an exception, always when i do dataWriter.Write(features);
Exception is:
{System.TypeInitializationException: The type initializer for 'NetTopologySuite.IO.DbaseEncodingUtility' threw an exception. ---> System.ArgumentNullException: Value cannot be null. Parameter name: key at System.Collections.Generic.Dictionary
2[TKey,TValue].FindEntry (TKey key) [0x00008] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs:380
at System.Collections.Generic.Dictionary2[TKey,TValue].ContainsKey (TKey key) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2019-08/android/release/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs:286 at NetTopologySuite.IO.DbaseEncodingUtility.AddLdidEncodingPair (System.Byte ldid, System.Text.Encoding encodingToAdd) [0x0000c] in <0e9c02ea98264091a344714de10def9b>:0 at NetTopologySuite.IO.DbaseEncodingUtility.RegisterEncodings (System.Object[][] ldidCodePagePairs) [0x00027] in <0e9c02ea98264091a344714de10def9b>:0 at NetTopologySuite.IO.DbaseEncodingUtility..cctor () [0x00799] in <0e9c02ea98264091a344714de10def9b>:0 --- End of inner exception stack trace --- at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_generic_class_init(intptr) at NetTopologySuite.IO.DbaseFileHeader.GetLdidFromEncoding (System.Text.Encoding encoding) [0x00000] in <0e9c02ea98264091a344714de10def9b>:0 at NetTopologySuite.IO.DbaseFileHeader.WriteHeader (System.IO.BinaryWriter writer) [0x0009b] in <0e9c02ea98264091a344714de10def9b>:0 at NetTopologySuite.IO.DbaseFileWriter.Write (NetTopologySuite.IO.DbaseFileHeader header) [0x00066] in <0e9c02ea98264091a344714de10def9b>:0 at NetTopologySuite.IO.ShapefileDataWriter.Write (System.Collections.Generic.IEnumerable
1[T] featureCollection) [0x00086] in <0e9c02ea98264091a344714de10def9b>:0
at GeoAraba.Helpers.Wkt2ShapeHelper.Transform (System.String wkt, System.String name) [0x00180] in D:\Workspace\VisualStudio\d-1815_geoaraba\GeoAraba\GeoAraba.Shared\Helpers\Wkt2ShapeHelper.cs:95 }`
I'm really lost, and desperate. Please, someone help me with this issue?
Thanks in advance.
In the DBaseFileHeader, we determine with the following logic if the Type is an Int32 or Int64:
If we create a Header based on a feature, the following logic is used:
This means an Int32 is defined with a length of 10 when writting. If you would read this header again, using the DBaseFieldDescriptor logic, it would be turn into an Int64 instead of an Int32.
From @tdyen on April 9, 2018 3:40
In DbaseFileWriter.cs if you Write a DateTime attribute for DateTime.MinValue then the year is 1 so it writes 1 char not 4 and you get this code triggered
// Check if the correct amount of bytes was written
if (bytesWritten != recordLength)
throw new ShapefileException("Error writing Dbase record");
So this method here
private void Write(DateTime date)
{
foreach (var c in date.Year.ToString(NumberFormatInfo.InvariantInfo))
_writer.Write(c);
ought to be something like this, though I haven't tested it
private void Write(DateTime date)
{
foreach (var c in date.ToString("yyyy", NumberFormatInfo.InvariantInfo))
_writer.Write(c);
Copied from original issue: NetTopologySuite/NetTopologySuite#226
The default is ThrowException
, this works. Null
also works, it ends up creating an empty multilinestring. Empty
and TryFix
don't work, they modify sequences[s]
but this modified data is not used in the later code. factory.CreateLineString(points)
throws because there is still only one point in points
.
I assume this wasn't fully tested when introduced in NetTopologySuite/NetTopologySuite@9942331
Replacing sequences[s]
with points
makes Empty
return an empty linestring, and makes TryFix
return a linestring with two coordinates at the same position. This was probably the intent of the original code.
Hi,
I'm looking to migrate away from an internal shapefile library (very old NTS fork + modifications), to this module. While figuring out how to use the API, I've also reviewed it and found that there is room for improvement. Most notably, IEnumerable<T>
should be added to the non-Extended
classes, but it's not a quick fix that I can do in a small PR. ShapefileDataReader
currently outputs an ICustomTypeDescriptor
backed by an internal type, which is not ideal.
A number of things that I would like to improve on:
IEnumerable<T>
ArrayList
to hold attributes) and pull this API out of the .NET 1.x eraExtended
classes into the non-Extended
classesIDataReader
implementation, doesn't really make sense and some methods have nonsense implementations (e.g. return 0;
no matter the method arguments)[TestCase(@"D:\Daten\Geofabrik\roads.shp")]
I should be able to do a good part of the necessary work, but I would like input from the current maintainers before going ahead.
Below is the public API of the read-related classes that I reviewed. I have not (yet) gone over write-related classes because they're not the focus of the project I work on. (The list was compiled by hand, so there may be errors.)
NetTopologySuite.IO.DbaseFileReader
Implements: System.Collections.IEnumerable
DbaseFileReader(NetTopologySuite.IO.Streams.IStreamProviderRegistry streamProviderRegistry)
DbaseFileReader(string path)
DbaseFileReader(string path, System.Text.Encoding encoding)
System.Collections.IEnumerator GetEnumerator()
NetTopologySuite.IO.DbaseFileHeader GetHeader()
NetTopologySuite.IO.ShapeFile.Extended.DBaseReader
Implements: System.IDisposable
, System.Collections.Generic.IEnumerable<NetTopologySuite.Features.IAttributesTable>
DbaseReader(NetTopologySuite.IO.Streams.IStreamProvider streamProvider)
DbaseReader(string filename)
void Dispose()
System.Collections.Generic.IEnumerator<NetTopologySuite.Features.IAttributesTable> GetEnumerator()
NetTopologySuite.Features.IAttributesTable ReadEntry(int index)
NetTopologySuite.IO.ShapefileReader
Implements: System.Collections.IEnumerable
ShapefileReader(NetTopologySuite.IO.Streams.IStreamProviderRegistry shapeStreamProviderRegistry, NetTopologySuite.Geometries.GeometryFactory geometryFactory)
ShapefileReader(string filename)
ShapefileReader(string filename, NetTopologySuite.Geometries.GeometryFactory geometryFactory)
System.Collections.IEnumerator GetEnumerator()
NetTopologySuite.Geometries.GeometryCollection ReadAll()
NetTopologySuite.IO.ShapefileHeader Header { get; }
NetTopologySuite.IO.ShapeFile.Extended.ShapeReader
Implements: System.IDisposable
ShapeReader(NetTopologySuite.IO.Streams.IStreamProviderRegistry streamProviderRegistry)
ShapeReader(string shapefilePath)
void Dispose()
System.Collections.Generic.IEnumerable<NetTopologySuite.Geometries.Geometry> ReadAllShapes(NetTopologySuite.Geometries.GeometryFactory geoFactory)
System.Collections.Generic.IEnumerable<NetTopologySuite.IO.Handlers.MBRInfo> ReadMBRs()
NetTopologySuite.Geometries.Geometry ReadShapeAtIndex(int index, NetTopologySuite.Geometries.GeometryFactory geoFactory)
NetTopologySuite.Geometries.Geometry ReadShapeAtOffset(long shapeOffset, NetTopologySuite.Geometries.GeometryFactory geoFactory)
NetTopologySuite.IO.ShapefileHeader ShapefileHeader { get; }
NetTopologySuite.IO.ShapefileDataReader
Implements: System.Data.IDataReader
, System.IDisposable
, System.Collections.IEnumerable
ShapefileDataReader(NetTopologySuite.IO.Streams.IStreamProviderRegistry streamProviderRegistry, NetTopologySuite.Geometries.GeometryFactory geometryFactory)
ShapefileDataReader(string filename, NetTopologySuite.Geometries.GeometryFactory geometryFactory)
ShapefileDataReader(string filename, NetTopologySuite.Geometries.GeometryFactory geometryFactory, System.Text.Encoding encoding)
void Close()
void Dispose()
bool GetBoolean(int i)
byte GetByte(int i)
long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
char GetChar(int i)
long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
System.Data.IDataReader GetData(int i)
string GetDataTypeName(int i)
System.DateTime GetDateTime(int i)
decimal GetDecimal(int i)
double GetDouble(int i)
System.Collections.IEnumerator GetEnumerator()
System.Type GetFieldType(int i)
float GetFloat(int i)
System.Guid GetGuid(int i)
short GetInt16(int i)
int GetInt32(int i)
long GetInt64(int i)
string GetName(int i)
int GetOrdinal(string name)
System.Data.DataTable GetSchemaTable()
string GetString(int i)
object GetValue(int i)
int GetValues(object[] values)
bool IsDBNull(int i)
bool NextResult()
bool Read()
void Reset()
NetTopologySuite.IO.DbaseFileHeader DbaseHeader { get; }
int Depth { get; }
int FieldCount { get; }
NetTopologySuite.Geometries.Geometry Geometry { get; }
bool IsClosed { get; }
int RecordCount { get; }
int RecordsAffected { get; }
NetTopologySuite.IO.ShapefileHeader ShapeHeader { get; }
object this[int i] { get; }
object this[string name] { get; }
NetTopologySuite.IO.ShapeFile.Extended.ShapeDataReader
Implements: System.IDisposable
ShapeDataReader(NetTopologySuite.IO.Streams.IStreamProviderRegistry streamProviderRegistry)
ShapeDataReader(NetTopologySuite.IO.Streams.IStreamProviderRegistry streamProviderRegistry, NetTopologySuite.Index.ISpatialIndex<NetTopologySuite.IO.Handlers.ShapeLocationInFileInfo> index)
ShapeDataReader(NetTopologySuite.IO.Streams.IStreamProviderRegistry streamProviderRegistry, NetTopologySuite.Index.ISpatialIndex<NetTopologySuite.IO.Handlers.ShapeLocationInFileInfo> index, NetTopologySuite.Geometries.GeometryFactory geoFactory)
ShapeDataReader(NetTopologySuite.IO.Streams.IStreamProviderRegistry streamProviderRegistry, NetTopologySuite.Index.ISpatialIndex<NetTopologySuite.IO.Handlers.ShapeLocationInFileInfo> index, NetTopologySuite.Geometries.GeometryFactory geoFactory, bool buildIndexAsync)
ShapeDataReader(string shapeFilePath)
ShapeDataReader(string shapeFilePath, NetTopologySuite.Index.ISpatialIndex<NetTopologySuite.IO.Handlers.ShapeLocationInFileInfo> index)
ShapeDataReader(string shapeFilePath, NetTopologySuite.Index.ISpatialIndex<NetTopologySuite.IO.Handlers.ShapeLocationInFileInfo> index, NetTopologySuite.Geometries.GeometryFactory geoFactory)
ShapeDataReader(string shapeFilePath, NetTopologySuite.Index.ISpatialIndex<NetTopologySuite.IO.Handlers.ShapeLocationInFileInfo> index, NetTopologySuite.Geometries.GeometryFactory geoFactory, bool buildIndexAsync)
void Dispose()
System.Collections.Generic.IEnumerable<NetTopologySuite.IO.ShapeFile.Extended.Entities.IShapefileFeature> ReadByMBRFilter(NetTopologySuite.Geometries.Envelope envelope, [bool testGeometriesActuallyInMBR = False])
NetTopologySuite.Geometries.Envelope ShapefileBounds { get; }
In DbaseFileHeader class line 311
string name = DbaseEncodingUtility.Latin1.GetString(buffer, 0, buffer.Length);
when the field value is Chinese character, it cant get the correct value.
it should be use the Detected encoding from line 294
var encoding = DetectEncoding(ldid, cpgStreamProvider);
to encoding the value,
string name = encoding.GetString(buffer, 0, buffer.Length);
then it get the correct value
I want to change the way the shapefile read/write works now:
Anyone have any feedback? Should I do this outside of the main NTS project, create a project/package in a new repo?
I was dealing with some shapefiles with possibly incorrect data for some shapes and I came across a situation where there are two polygons. One contains only 2 points (which is invalid) followed by a second valid polygon of 21 points. However on this situation the enumerator is aborted prematurely before the end of the file, due to the catch()
block (ShapefileReader.cs line 138)
try
{
int recordNumber = _shpBinaryReader.ReadInt32BE();
int contentLength = _shpBinaryReader.ReadInt32BE();
_geometry = _handler.Read(_shpBinaryReader, contentLength, _parent._geometryFactory);
}
catch (Exception ex)
{
// actually we should remove this crap...
Trace.WriteLine(ex.Message);
return false; // <----------------- will ignore further valid shapes
}
I would suggest to proceed the enumeration until the end of the file is reached, so possibly valid shapes are not ignored.
I'm starting with NetTopologySuite and I'm trying to read an .shp that I created from geojson.io to do some tests, it gave me an .zip file which contains 4 files (.dbf, .prj, .shp and .shx).
When I try to read the .shp alone I'm having the error: "System.IO.FileNotFoundException: '.../POLYGON.dbf'".
When I try to read the .shp with the .dbf in the same folder I'm having the error: "System.NotSupportedException: 'Unsupported DBF reader Type 13'".
I tried to open this .shp in QGIS and it worked.
I tried to read other .shp files from other sources with my code and it worked.
Code:
ShapeDataReader reader = new ShapeDataReader("...\\POLYGON.shp");
File:
polygon.zip
NetTopologySuite.IO.ShapeFile version: 1.15.3
From @majorbenks on March 16, 2018 8:35
I tried to use ShapefileDataWriter with a ShapefileStreamProviderRegistry. I open four FileStreams and wrap them in an object implementing IShapefileStreamProvider adding them to a ShapefileStreamProviderRegistry. When I run my code, a System.ObjectDisposedException 'Cannot access a closed file.' is thrown. My code works fine when I use a file path instead of streams.
Hier is my the code:
using (var shpStream = File.Create(Path.Combine(pathWithoutFilename, $"{fileNameWithoutEnding}.shp")))
{
using (var shxStream = File.Create(Path.Combine(pathWithoutFilename, $"{fileNameWithoutEnding}.shx")))
{
using (var dbfStream = File.Create(Path.Combine(pathWithoutFilename, $"{fileNameWithoutEnding}.dbf")))
{
using (var prjStream = File.Create(Path.Combine(pathWithoutFilename, $"{fileNameWithoutEnding}.prf")))
{
var registry = new ShapefileStreamProviderRegistry(
new ShapeFileStreamProvider(shpStream, StreamTypes.Shape),
new ShapeFileStreamProvider(shxStream, StreamTypes.Index),
new ShapeFileStreamProvider(dbfStream, StreamTypes.Data));
// Create the projection file
using (var streamWriter = new StreamWriter(prjStream))
{
streamWriter.Write(shapeFilePrjString);
}
// Create the shapefile
var outGeomFactory = GeometryFactory.Default;
var writer = new ShapefileDataWriter(registry, outGeomFactory, Encoding.UTF8);
var outDbaseHeader = ShapefileDataWriter.GetHeader(features[0], features.Count);
writer.Header = outDbaseHeader;
writer.Write(features);
}
}
}
}
This is the stack trace:
at System.IO.__Error.FileNotOpen()
at System.IO.FileStream.Flush(Boolean flushToDisk)
at System.IO.FileStream.Flush()
at System.IO.BinaryWriter.Flush()
at System.IO.BinaryWriter.get_BaseStream()
at NetTopologySuite.IO.DbaseFileWriter.Write(DbaseFileHeader header)
at NetTopologySuite.IO.ShapefileDataWriter.Write(IList1 featureCollection) at Softec.GIS.GeometrieDatenImportExport.FileAccess.SaveToShapeFile(String pathWithoutFilename, String fileNameWithoutEnding, String shapeFilePrjString, IList
1 features) in C:\Projekte\Softec.GIS.GeometrieDatenImportExport.Console\Softec.GIS.GeometrieDatenImportExport\FileAccess.cs:line 72
at Softec.GIS.GeometrieDatenImportExport.ShapeExporter.ExportToShapeFile(List`1 models, String pathWithoutFilename, String fileNameWithoutEnding) in C:\Projekte\Softec.GIS.GeometrieDatenImportExport.Console\Softec.GIS.GeometrieDatenImportExport\ShapeExporter.cs:line 82
at Softec.GIS.GeometrieDatenImportExport.Console.Program.Main(String[] args) in C:\Projekte\Softec.GIS.GeometrieDatenImportExport.Console\Softec.GIS.GeometrieDatenImportExport.Console\Program.cs:line 31
Google research suggests, that the stream is closed somewhere, but I can't figure out where. I don't close it anywhere. Can anyone help? Or is this a bug?
I'm using NetTopologySuite v1.14.0, NetTopologySuite.IO. v1.14.0.1, NET FW 4.6.1, WIN 10 Pro and it is a console application.
Copied from original issue: NetTopologySuite/NetTopologySuite#223
If we write a feature without attributes, we get an System.OverflowException : Arithmetic operation resulted in an overflow
when reading the header again. the error occurs on the following line:
-1
and this is because of the calculation above, where the _headerLength is 0 and FileDescriptorSize defaults to 32.Currently the header length is only set when adding or removing columns to the header.
Add Column
My proposed solution is to check the headerLength when writing and set it to 33 when it is 0.
Hi!
I am trying to convert a .net standard applikation to .net core and get a runtime exception from the IO.ShapeFile library. I have added the nuget NetTopologySuite.IO.Shapefile in VS code, and my target framework is netcoreapp2.0. VS Code says everything is compatible.
The exception is thrown when reading a shapefile:
GeometryFactory factory = new GeometryFactory(new PrecisionModel(PrecisionModels.Fixed),3006);
var features = new List<Feature>();
using ( ShapefileDataReader shapeFileDataReader = new ShapefileDataReader(shpFilename, factory)) {
It seems like maybe the DbaseEncodeUtility tries to load .Net 4.1 assemblies for System.Text.Encoding?
{System.IO.FileNotFoundException: Could not load file or assembly 'System.Text.Encoding.CodePages, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
File name: 'System.Text.Encoding.CodePages, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at NetTopologySuite.IO.DbaseEncodingUtility.GetEncodingForCodePageName(String name)
at NetTopologySuite.IO.DbaseEncodingUtility..cctor() in D:\Development\Source\Repos\NTS.IO\NetTopologySuite.IO.ShapeFile\NetTopologySuite.IO.GeoTools\Dbase\DbaseEncodingUtility.cs:line 14
Or am I doing something wrong?
Thanks
I am reading in a shape file using to test my code:
var reader = new ShapeDataReader(path);
var bounds = reader.ShapefileBounds;
foreach (var thing in reader.ReadByMBRFilter(bounds))
{
var attrs = thing.Attributes;
var geo = thing.Geometry;
if (geo != null)
{
var coords = geo.Coordinates;
}
}
path
is the path to the .shp
file. Is this correct? Or should I be using ShapefileDataReader
? I've seen examples online of both.
One thing is that I can't figure out how to get the coordinate system via code. I need to project it to WGS84. The srid on the geometry is 0 so I'm not sure how to get the information I need. Do I need to do something special to read the .prj
file to get the information I need?
Running all the NUnit tests from a clean clone on VS2017, most of them fail on my machine.
Some of the failures are because the tests are run on netcoreapp2.0
(so using netstandard2.0
), which doesn't handhold as much as the "fat" .NET targets and has a few different defaults around encodings.
how can i create a new shapefile ?
In this line you're trying to use content of cpg file as is. But whitespaces, line endings, etc prevents to detect correct encoding.
E.g. these lines will lead to ArgumentException which will lead to default encoding instead of desirable.
Encoding.GetEncoding("UTF-8/r/n")
Encoding.GetEncoding("UTF-8 ")
Suggestion - trim leading and trailing whitespaces.
I am creating a Xamarin.Forms App across UWP and Android with .NetStandard.
Since I have a thight deadline a quick answer would be great!
Thank you very much!
From @trailway on July 19, 2016 17:57
I recently encountered some shape files which the reader does not handle. It can be debated whether the files are correct but they do work in ArcMap! What happens is that the content length does not include M content which is present (although it's presence is benign because the value says that it is not meaningful). This makes the reader fail because it walks through shape geometry using content length, i.e. it expects the next element to begin at the location just after the location where the previous element ended. This works in ArcMap because they use the shape index. I think that using the shape index (which is a required file) is a more stable approach.
Copied from original issue: NetTopologySuite/NetTopologySuite#112
var writer =new ShapefileDataWriter(fullpath, factory,writeEncoding);
writer.Header = ShapefileDataWriter.GetHeader(lines[0], lines.Count);
default is 3D coordinates? i need to 2d
NetTopologySuite/NetTopologySuite@19f2f40 introduced ShapeHandler.GeometryInstantiationErrorHandling
, but this property is only accessible through an instance of a handler. When using ShapefileReader
, the handler is a private field of the ShapefileEnumerator
class, making it impossible to change the value of this property.
Relevant code:
Hello!
I am working out how to read shapefiles cross platform (UWP and Android) in a Xamarin.Forms application (.netstandard 2.0). But I am encountering an issue:
System.ArgumentNullException
Message=Value cannot be null.
Parameter name: key
this exception is thrown in the line
var shapeFileReader = Shapefile.CreateDataReader(shapeFile,
new NetTopologySuite.Geometries.GeometryFactory(
new NetTopologySuite.Geometries.PrecisionModel(1000000.0)));
where 'shapeFile' is a string with the path /data/user/0/com.companyname.shapefileforms/cache/ShapeFiles/countries
(so without file extensions).
This code works fine when run as UWP app but not when run within Android. Tested with version 8.1, 9 and 10.
I attached the whole Project. This error occurs in ShapeFileForms.MainPage.xaml.cs in the Method ClickOnMap, line 83.
I can not step into this line in the debugger, I guess because I installed this module through nuget instead of copying in its source code?
It would be awesome if we could work this out together, although I am quite new to this and pobably won't be of much help :/
Thank you very much!
Hi,
I'm trying to create ShapeFile which contains time-specific values.
At first, I tried to just add DateTime fields to Attributes table just using:
attributesTable.Add("DateTime", myObject.MyDateTimeField));
,
but according to ShapeFileDataWriter:
else if (type == typeof(DateTime)) header.AddColumn(name, 'D', DateLength, DateDecimals);
and DbFileWriter:
else if (columnValue is DateTime)
{
Write((DateTime)columnValue);
}
...
/// <summary>
/// </summary>
/// <param name="date"></param>
private void Write(DateTime date)
{
foreach (char c in date.Year.ToString(NumberFormatInfo.InvariantInfo))
_writer.Write(c);
if (date.Month < 10)
_writer.Write('0');
foreach (char c in date.Month.ToString(NumberFormatInfo.InvariantInfo))
_writer.Write(c);
if (date.Day < 10)
_writer.Write('0');
foreach (char c in date.Day.ToString(NumberFormatInfo.InvariantInfo))
_writer.Write(c);
}
DateTime is always converted to Date format.
So I started to search how to place Time in dbf file, and found in documentation that there is a Timestamp field which has @ symbol.
I tried to change symbol in shape file header, but I See that there are a few places that should be fixed to use Timestamp field.
My question is: In actual code is there a way to place in .shp/.dbf files not only date but also a time and mark it as @ timestamp?
Is there a reason why it's not supported? Is my documentation wrong or is there any other reason?
If there just never be any need to use timestamp before could I contribute and add that functionality? :)
This example:
var geomFactory = new GeometryFactory();
var features = new List<IFeature>();
var attrTbl = new AttributesTable();
attrTbl.Add("Id", 10);
var coordinates = new Coordinate[2];
coordinates[0] = new Coordinate(123.0, 023.0);
coordinates[1] = new Coordinate(123.0, 100.0);
var mPoint = geomFactory.CreateMultiPointFromCoords(coordinates);
var ft = new Feature(mPoint, attrTbl);
features.Add(ft);
var shpWriter = new ShapefileDataWriter("outShape.shp", geomFactory);
var header = ShapefileDataWriter.GetHeader(features[0], features.Count);
shpWriter.Header = header;
shpWriter.Write(features);
Failes int the last Write call with exception:
System.ArgumentException: Expected geometry that implements 'IPoint', but was 'MultiPoint'
This is because the call from Write to Shapefile.GetShapeType() with the first geometry returns
PointZM bacause the call to GetNonEmptyGeometry uses GetGeometryN() to get the first point in the mulitpoint and returns it.
The function GetNonEmptyGeometry() could return the geometry itself if it is not null in this case or maby Shapefile.GetShapeType() could not use it to filter geometry.
I filed NetTopologySuite/NetTopologySuite#397
Not sure if that's the spot for this issue or this is.
set encoding error:
this my code sample:
ShapefileDataWriter.GetHeader(features[0], features.Count,Encoding.UTF8);
error msg:
Setting the encoding is only allowed once, either by means of the constructor or this property setter
and chinese random code error
having an issue where i would like to read from a shape file, dispose the reader but hold the shape file information to do something with later. something like:
private static IEnumerable<NetTopologySuite.IO.ShapeFile.Extended.Entities.IShapefileFeature> ProcessShapeFile(string shapeFilePath)
{
using (ShapeDataReader reader = new ShapeDataReader(shapeFilePath))
{
NetTopologySuite.Geometries.Envelope mbr = reader.ShapefileBounds;
return reader.ReadByMBRFilter(mbr).ToList();
}
}
and then later, in another method that
var feats = ProcessShapeFile(path);
foreach (NetTopologySuite.IO.ShapeFile.Extended.Entities.IShapefileFeature f in feats)
{
string clevelVal = f.Attributes["attName"];
...
}
on the attribute line, i get the following error:
System.InvalidOperationException: Reader was disposed, cannot read from a disposed reader
Stack Trace:
DbaseReader.ReadEntry(Int32 index)
<.ctor>b__1()
Lazy1.CreateValue() Lazy
1.LazyInitValue()
Lazy`1.get_Value()
IFeature.get_Attributes()
is there any way to get what i'm looking for here, or can i not centralize the shape file loading/disposing like i'm hoping to?
Describe
UTF-8 shapefile loaded with wrong encoding.
Code Snippet
using (var reader = new ShapefileDataReader("shape.shp", new GeometryFactory(),
Encoding.UTF8))
{
reader.Read();
}
Investigation
NetTopologySuite.IO.DbaseFileReader.CreateStreamProviderRegistry
method gets called atShapefileDataReader
constructor.
It passes encoding.EncodingName
to ByteStreamProvider
argument with "Unicode (UTF-8)"
value.
Later, when parsing the header in NetTopologySuite.IO.DbaseFileHeader.GetEncoding()
try
{
// The following line throws exception
// 'Unicode (UTF-8)' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
return DbaseEncodingUtility.GetEncodingForCodePageName(cpgText);
}
catch
{
return DefaultEncoding;
}
I think DbaseEncodingUtility.GetEncodingForCodePageName
should be called with "UTF-8" argument.
Registering encoding provider
Calling Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
does not fixes my issue.
Quick fix
Setting the default header encoding.
DbaseFileHeader.DefaultEncoding = Encoding.UTF8;
When writting a shape to a stream, I get the following error:
System.NotSupportedException : Memory stream is not expandable.
After doing some investigation I have found what the cause of this could be:
In here a new MemoryStream instance is created. When it is a user defined MemoryStream, you aren't able to let the stream grow.
See here a private _expandable
property being set.
https://referencesource.microsoft.com/#mscorlib/system/io/memorystream.cs,108
When setting the capacity, you will see that this is checked and will result into the exception described in the title.
https://referencesource.microsoft.com/#mscorlib/system/io/memorystream.cs,283
To solve this you could use the default contstructor, or the constructor where you only pass the capacity of the stream.
https://referencesource.microsoft.com/#mscorlib/system/io/memorystream.cs,70
Im trying to read shp-files in a Xamarin.Mac project with NetTopologySuite.IO.Shapefile 2.0.0.
Project is targeting Xamarin.Mac Full NET 4.8.
Calling _reader = new ShapefileDataReader(file, _geometryFactory, System.Text.Encoding.Default);
results in ArgumentNullException, see stacktrace below.
With a plain .NET Core 3.0 project, everything is fine.
Any ideas?
System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument argument) in /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/src/Xamarin.Mac/external/corefx/src/System.Memory/src/System/ThrowHelper.cs:27
System.Collections.Generic.Dictionary<System.Text.Encoding,byte>.FindEntry(System.Text.Encoding key) in /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/src/Xamarin.Mac/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs:380
System.Collections.Generic.Dictionary<System.Text.Encoding,byte>.ContainsKey(System.Text.Encoding key) in /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/src/Xamarin.Mac/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs:286
NetTopologySuite.IO.DbaseEncodingUtility.AddLdidEncodingPair(byte ldid, System.Text.Encoding encodingToAdd) in
NetTopologySuite.IO.DbaseEncodingUtility.RegisterEncodings(object[][] ldidCodePagePairs) in
NetTopologySuite.IO.DbaseEncodingUtility..cctor() in
NetTopologySuite.IO.DbaseFileHeader.GetEncoding(NetTopologySuite.IO.Streams.ByteStreamProvider provider) in
NetTopologySuite.IO.DbaseFileHeader.DetectEncoding(byte ldid, NetTopologySuite.IO.Streams.ByteStreamProvider cpgFile) in
NetTopologySuite.IO.DbaseFileHeader.ReadHeader(System.IO.BinaryReader reader, NetTopologySuite.IO.Streams.ByteStreamProvider cpgStreamProvider) in
NetTopologySuite.IO.DbaseFileReader.GetHeader() in
NetTopologySuite.IO.ShapefileDataReader..ctor(string filename, NetTopologySuite.Geometries.GeometryFactory geometryFactory, System.Text.ASCIIEncoding encoding) in
QvShape.Reader..ctor(string file) in /Users/tomflemming/QuoVadis/Qvx1/CodeFromExternal/NetTopologySuite/QvShape/Reader.cs:26
QvShape.Reader.Test() in /Users/tomflemming/QuoVadis/Qvx1/CodeFromExternal/NetTopologySuite/QvShape/Reader.cs:83
QvxAppShared.QvxApp..ctor(Eto.Mac.Platform platform, string[] args) in /Users/tomflemming/QuoVadis/Qvx1/QvxShared/App/QvxApp.cs:49
QvxAppShared.Mac.Program.Main(string[] args) in /Users/tomflemming/QuoVadis/Qvx1/QvxMac/Program.cs:16
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.