diff --git a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericDecimalField.cs b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericDecimalField.cs new file mode 100644 index 0000000..017ae7f --- /dev/null +++ b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericDecimalField.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace NetTopologySuite.IO.Esri.Dbf.Fields +{ + /// + /// Int64 field definition. + /// + public class DbfNumericDecimalField : DbfNumericField + { + /// + /// Intializes new instance of the numerif field class. + /// + /// Field name. + /// The number of significant digits (including decimal separator). + /// The number of fractional digits. + public DbfNumericDecimalField(string name, int length, int precision) + : base(name, DbfType.Numeric, length, precision) + { + } + + /// + /// Initializes a new instance of the field class. + /// + /// Field name. + public DbfNumericDecimalField(string name) : this(name, MaxFieldLength, MaxFieldPrecision) + { + } + + /// + protected override decimal StringToNumber(string s) + { + return decimal.Parse(s, CultureInfo.InvariantCulture); + } + } +} diff --git a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericDoubleField.cs b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericDoubleField.cs index c7a802b..8c79f6e 100644 --- a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericDoubleField.cs +++ b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericDoubleField.cs @@ -10,6 +10,8 @@ namespace NetTopologySuite.IO.Esri.Dbf.Fields /// public class DbfNumericDoubleField : DbfNumericField { + internal static readonly int DefaultFieldLength = 19; // 17 digits + decimal separator + sign https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types#characteristics-of-the-floating-point-types + /// /// Intializes new instance of the numerif field class. /// diff --git a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericField.cs b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericField.cs index 7cce612..e671588 100644 --- a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericField.cs +++ b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericField.cs @@ -37,12 +37,17 @@ internal static DbfField Create(string name, int length, int precision) return new DbfNumericInt32Field(name, length); } - if (precision <= 0) + if (precision <= 0 && length <= DbfNumericInt64Field.DefaultFieldLength) { return new DbfNumericInt64Field(name, length); } - return new DbfNumericDoubleField(name, length, precision); + if (length <= DbfNumericDoubleField.DefaultFieldLength) + { + return new DbfNumericDoubleField(name, length, precision); + } + + return new DbfNumericDecimalField(name, length, precision); } } diff --git a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericInt32Field.cs b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericInt32Field.cs index 9bcb511..2c59745 100644 --- a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericInt32Field.cs +++ b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericInt32Field.cs @@ -10,7 +10,7 @@ namespace NetTopologySuite.IO.Esri.Dbf.Fields /// public class DbfNumericInt32Field : DbfNumericField { - internal static readonly int DefaultFieldLength = 10; //-2147483648..2147483647 => 11, but Esri uses 10 + internal static readonly int DefaultFieldLength = 10; //-2147483648..2147483647 (11..10 digits) /// /// Intializes new instance of the numerif field class. diff --git a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericInt64Field.cs b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericInt64Field.cs index 2efeace..77f3d2a 100644 --- a/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericInt64Field.cs +++ b/src/NetTopologySuite.IO.Esri.Shapefile/Dbf/Fields/DbfNumericInt64Field.cs @@ -10,6 +10,8 @@ namespace NetTopologySuite.IO.Esri.Dbf.Fields /// public class DbfNumericInt64Field : DbfNumericField { + internal static readonly int DefaultFieldLength = 19; // -9223372036854775808 to 9223372036854775807 (20..19 digits) + /// /// Intializes new instance of the numerif field class. /// diff --git a/test/NetTopologySuite.IO.Esri.Test/Issues/Issue049.cs b/test/NetTopologySuite.IO.Esri.Test/Issues/Issue049.cs new file mode 100644 index 0000000..e74d275 --- /dev/null +++ b/test/NetTopologySuite.IO.Esri.Test/Issues/Issue049.cs @@ -0,0 +1,30 @@ +using NetTopologySuite.IO.Esri.Shapefiles.Readers; +using NUnit.Framework; + +namespace NetTopologySuite.IO.Esri.Test.Issues; + +/// +/// https://github.com/NetTopologySuite/NetTopologySuite.IO.Esri/issues/49 +/// +internal class Issue049 +{ + [Test] + public void Decimal0_OpenShapefile() + { + var shpPath = TestShapefiles.PathTo("Issues/049/221-1_28.03.202411-16.shp"); + var options = new ShapefileReaderOptions + { + GeometryBuilderMode = GeometryBuilderMode.FixInvalidShapes + }; + using var shpReader = Shapefile.OpenRead(shpPath, options); + + Assert.AreEqual(shpReader.ShapeType, ShapeType.Polygon); + + while (shpReader.Read()) + { + var dosis = shpReader.Fields["DOSIS"].Value.ToString(); + Assert.IsNotEmpty(dosis); + Assert.IsFalse(shpReader.Geometry.IsEmpty); + } + } +} diff --git a/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.dbf b/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.dbf new file mode 100644 index 0000000..1ce6268 Binary files /dev/null and b/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.dbf differ diff --git a/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.prj b/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.prj new file mode 100644 index 0000000..a30c00a --- /dev/null +++ b/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.prj @@ -0,0 +1 @@ +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] \ No newline at end of file diff --git a/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.shp b/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.shp new file mode 100644 index 0000000..e62c8ac Binary files /dev/null and b/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.shp differ diff --git a/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.shx b/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.shx new file mode 100644 index 0000000..ce0559e Binary files /dev/null and b/test/TestData/TestShapefiles/Issues/049/221-1_28.03.202411-16.shx differ