From d8acc12b74a03cbee2948dc68ccdd35977959d20 Mon Sep 17 00:00:00 2001 From: Martin Boje Carpentier Date: Sun, 2 Jan 2022 09:59:45 +0100 Subject: [PATCH 01/22] Run release from ubuntu --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 356fb7b..b4c01e6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: deploy: name: 'Deploy to Nuget' if: github.event_name == 'release' - runs-on: windows-2019 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 From cbe8a165160458353019f63b957d70a7f971df02 Mon Sep 17 00:00:00 2001 From: Martin Carpentier Date: Sat, 8 Jan 2022 20:11:04 +0100 Subject: [PATCH 02/22] The nuget push input folder was incorrect --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 84d884f..aeea514 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,4 +48,4 @@ jobs: } dotnet pack -v normal -c Release --include-symbols --include-source -p:PackageVersion=$VERSION -o nupkg src/${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj - name: Push to Nuget - run: dotnet nuget push nuget/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate \ No newline at end of file + run: dotnet nuget push nupkg/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate \ No newline at end of file From 50263599dee2172611cb5d35b450d0d3ac7904fd Mon Sep 17 00:00:00 2001 From: Martin Boje Carpentier Date: Tue, 11 Jan 2022 13:58:18 +0100 Subject: [PATCH 03/22] There is no support for wildcard in the dotnet nuget push command, so i edited the command, to first retrieve the most recent nupkg package using Get-ChildItem which supports wildcards, and then push the result --- .github/workflows/release.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a2d90b6..6f061dd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: deploy: name: 'Deploy to Nuget' if: github.event_name == 'release' - runs-on: ubuntu-20.04 + runs-on: windows-2019 steps: - uses: actions/checkout@v2 @@ -48,4 +48,8 @@ jobs: } dotnet pack -v normal -c Release --include-symbols --include-source -p:PackageVersion=$VERSION -o nupkg src/${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj - name: Push to Nuget - run: dotnet nuget push nupkg/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate \ No newline at end of file + run: | + gci ./nupkg/*.nupkg | + sort LastWriteTime -Descending | + select -First 1 | + % { dotnet nuget push $_.FullName --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate } From 991b63e52d64aac7b997f96a1918fd01f108ab7f Mon Sep 17 00:00:00 2001 From: Martin Boje Carpentier Date: Wed, 26 Jan 2022 15:09:58 +0100 Subject: [PATCH 04/22] Push package by id directly --- .github/workflows/release.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6f061dd..c24c317 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,8 +48,4 @@ jobs: } dotnet pack -v normal -c Release --include-symbols --include-source -p:PackageVersion=$VERSION -o nupkg src/${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj - name: Push to Nuget - run: | - gci ./nupkg/*.nupkg | - sort LastWriteTime -Descending | - select -First 1 | - % { dotnet nuget push $_.FullName --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate } + run: dotnet nuget push ./nupkg/${{ env.PROJECT_NAME }}.${{ $VERSION }}.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate } From d2a59b6de3d5e98d41deaaeb3a2201e624988c6a Mon Sep 17 00:00:00 2001 From: Martin Boje Carpentier Date: Wed, 26 Jan 2022 20:43:06 +0100 Subject: [PATCH 05/22] Updated the release version variable --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c24c317..7056fb1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,4 +48,4 @@ jobs: } dotnet pack -v normal -c Release --include-symbols --include-source -p:PackageVersion=$VERSION -o nupkg src/${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj - name: Push to Nuget - run: dotnet nuget push ./nupkg/${{ env.PROJECT_NAME }}.${{ $VERSION }}.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate } + run: dotnet nuget push "./nupkg/${{ env.PROJECT_NAME }}.$VERSION.nupkg" --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate From 4aea7e60e1a79a3eda3724f4b89d840792a6eb32 Mon Sep 17 00:00:00 2001 From: Martin Boje Carpentier Date: Wed, 26 Jan 2022 21:48:00 +0100 Subject: [PATCH 06/22] Only .net core 3.1 is needed to build .net standard --- .github/workflows/release.yml | 28 +++++++++++++++------------- src/GeoJSON.Text.sln | 1 + 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7056fb1..4a22b78 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ env: # Official NuGet Feed settings NUGET_FEED: https://api.nuget.org/v3/index.json NUGET_KEY: ${{ secrets.NUGET_KEY }} - NUGET_VERSIONING_REGEX: "[0-9]+\\.[0-9]+\\.[0-9]+-[a-zA-Z]+" + NUGET_VERSIONING_REGEX: "[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z]+)?" jobs: deploy: @@ -24,7 +24,18 @@ jobs: runs-on: windows-2019 steps: - - uses: actions/checkout@v2 + - name: Validate release version + run: | + $VERSION=${env:GITHUB_REF_NAME} + if($VERSION[0] -eq "v"){ + $VERSION=$VERSION.substring(1) + } + if(!($VERSION -match ${env:NUGET_VERSIONING_REGEX})) { + throw "Release tag did not contain a valid NUGET version. TAG was : ${env:GITHUB_REF_NAME}" + } + echo "Version to use is - $VERSION" + echo "RELEASE_VERSION=$VERSION" | Out-File -FilePath ${env:GITHUB_ENV} -Append + - uses: actions/checkout@v2 - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: @@ -37,15 +48,6 @@ jobs: - name: Build solution run: dotnet build src/${{ env.PROJECT_NAME }}.sln -c Release --no-restore - name: Create Release NuGet package - run: | - $VERSION=${env:GITHUB_REF_NAME} - if($VERSION[0] -eq "v"){ - $VERSION=$VERSION.substring(1) - } - - if(!($VERSION -match ${env:NUGET_VERSIONING_REGEX})) { - throw "Release tag did not contain a valid NUGET version. TAG was : ${env:GITHUB_REF_NAME}" - } - dotnet pack -v normal -c Release --include-symbols --include-source -p:PackageVersion=$VERSION -o nupkg src/${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj + run: dotnet pack -v normal -c Release --include-symbols --include-source -p:PackageVersion=${{ env.RELEASE_VERSION }} -o nupkg src/${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj - name: Push to Nuget - run: dotnet nuget push "./nupkg/${{ env.PROJECT_NAME }}.$VERSION.nupkg" --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate + run: dotnet nuget push "./nupkg/${{ env.PROJECT_NAME }}.${{ env.RELEASE_VERSION }}.nupkg" --source https://api.nuget.org/v3/index.json --api-key ${{secrets.NUGET_KEY}} --skip-duplicate diff --git a/src/GeoJSON.Text.sln b/src/GeoJSON.Text.sln index 1edb6f9..51d17e2 100644 --- a/src/GeoJSON.Text.sln +++ b/src/GeoJSON.Text.sln @@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\.github\workflows\continous-benchmark.yml = ..\.github\workflows\continous-benchmark.yml ..\LICENSE.md = ..\LICENSE.md ..\README.md = ..\README.md + ..\.github\workflows\release.yml = ..\.github\workflows\release.yml EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GeoJSON.Text", "GeoJSON.Text\GeoJSON.Text.csproj", "{ECD95D99-8429-4358-92AE-1C51061D774C}" From b473174aed73e8fea2ab3058350c57696940f0b0 Mon Sep 17 00:00:00 2001 From: Laura Laban Date: Wed, 16 Nov 2022 15:23:15 +0100 Subject: [PATCH 07/22] Fix for PositionConverter.Read SerializerSerializer - Issue #18 Passing the SerializationOptions along in the internal call to JsonSerializer in PositionConverter.Read(). See issue for details and repro with floating point string literals. --- src/GeoJSON.Text/Converters/PositionConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GeoJSON.Text/Converters/PositionConverter.cs b/src/GeoJSON.Text/Converters/PositionConverter.cs index fc78e4f..58abb40 100644 --- a/src/GeoJSON.Text/Converters/PositionConverter.cs +++ b/src/GeoJSON.Text/Converters/PositionConverter.cs @@ -44,7 +44,7 @@ public override IPosition Read( try { - coordinates = JsonSerializer.Deserialize(ref reader); + coordinates = JsonSerializer.Deserialize(ref reader, options); } catch (Exception e) { From 38aced95ae5f2a6f23135be1dd1500d2ef3cc2b0 Mon Sep 17 00:00:00 2001 From: Matt Hunt Date: Fri, 2 Dec 2022 10:16:27 +0000 Subject: [PATCH 08/22] Correcting string values for GeoJSONObjectType --- src/GeoJSON.Text/GeoJSONObjectType.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/GeoJSON.Text/GeoJSONObjectType.cs b/src/GeoJSON.Text/GeoJSONObjectType.cs index e7dd7dc..ed3ae0e 100644 --- a/src/GeoJSON.Text/GeoJSONObjectType.cs +++ b/src/GeoJSON.Text/GeoJSONObjectType.cs @@ -15,7 +15,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.2 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "Point")] Point, /// @@ -24,7 +24,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.3 /// - [EnumMember(Value = "multipoint")] + [EnumMember(Value = "MultiPoint")] MultiPoint, /// @@ -33,7 +33,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.4 /// - [EnumMember(Value = "linestring")] + [EnumMember(Value = "LineString")] LineString, /// @@ -42,7 +42,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.5 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "MultiLineString")] MultiLineString, /// @@ -51,7 +51,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.6 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "Polygon")] Polygon, /// @@ -60,7 +60,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.7 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "MultiPolygon")] MultiPolygon, /// @@ -69,7 +69,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.8 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "GeometryCollection")] GeometryCollection, /// @@ -78,7 +78,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.2 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "Feature")] Feature, /// @@ -87,7 +87,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.3 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "FeatureCollection")] FeatureCollection } } From 6b79dbcd53166d552e13534e3af74d1ba0f7fadc Mon Sep 17 00:00:00 2001 From: Matt Hunt Date: Tue, 2 May 2023 10:34:50 +0100 Subject: [PATCH 09/22] Adding TypedFeatureCollection --- .../GeoJSON.Text.Test.Benchmark.csproj | 5 +- .../Feature/FeatureCollectionTests.cs | 262 +++++++++------- ...ollectionTests_Can_DeserializeGeneric.json | 76 +++++ .../GeoJSON.Text.Test.Unit.csproj | 5 +- src/GeoJSON.Text/Feature/FeatureCollection.cs | 294 +++++++++++++----- src/GeoJSON.Text/GeoJSON.Text.csproj | 7 +- 6 files changed, 433 insertions(+), 216 deletions(-) create mode 100644 src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests_Can_DeserializeGeneric.json diff --git a/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj b/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj index ab33be7..8aefd83 100644 --- a/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj +++ b/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj @@ -1,12 +1,11 @@  - Exe - netstandard2.0;net5;net6 + net6.0;net7.0;netstandard2.0 disable enable False - Latest + 10 diff --git a/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs b/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs index 3c6d6cf..5e6d47e 100644 --- a/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs +++ b/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs @@ -6,169 +6,189 @@ using GeoJSON.Text.Geometry; using NUnit.Framework; -namespace GeoJSON.Text.Tests.Feature +namespace GeoJSON.Text.Tests.Feature; + +[TestFixture] +public class FeatureCollectionTests : TestBase { - [TestFixture] - public class FeatureCollectionTests : TestBase + [Test] + public void Ctor_Throws_ArgumentNullException_When_Features_Is_Null() { - [Test] - public void Ctor_Throws_ArgumentNullException_When_Features_Is_Null() + Assert.Throws(() => { - Assert.Throws(() => - { - var featureCollection = new FeatureCollection(null); - }); - } + var featureCollection = new FeatureCollection(null); + }); + } - [Test] - public void Can_Deserialize() - { - string json = GetExpectedJson(); + [Test] + public void Can_Deserialize() + { + string json = GetExpectedJson(); - var featureCollection = JsonSerializer.Deserialize(json); + var featureCollection = JsonSerializer.Deserialize(json); - Assert.IsNotNull(featureCollection.Features); - Assert.AreEqual(featureCollection.Features.Count, 3); - Assert.AreEqual(featureCollection.Features.Count(x => x.Geometry.Type == GeoJSONObjectType.Point), 1); - Assert.AreEqual(featureCollection.Features.Count(x => x.Geometry.Type == GeoJSONObjectType.MultiPolygon), 1); - Assert.AreEqual(featureCollection.Features.Count(x => x.Geometry.Type == GeoJSONObjectType.Polygon), 1); - } + Assert.IsNotNull(featureCollection); + Assert.IsNotNull(featureCollection.Features); + Assert.AreEqual(featureCollection.Features.Count, 3); + Assert.AreEqual(featureCollection.Features.Count(x => x.Geometry.Type == GeoJSONObjectType.Point), 1); + Assert.AreEqual(featureCollection.Features.Count(x => x.Geometry.Type == GeoJSONObjectType.MultiPolygon), 1); + Assert.AreEqual(featureCollection.Features.Count(x => x.Geometry.Type == GeoJSONObjectType.Polygon), 1); + } - [Test] - public void FeatureCollectionSerialization() - { - var model = new FeatureCollection(); - for (var i = 10; i-- > 0;) - { - var geom = new LineString(new[] - { - new Position(51.010, -1.034), - new Position(51.010, -0.034) - }); + [Test] + public void Can_DeserializeGeneric() + { + string json = GetExpectedJson(); - var props = new Dictionary - { - { "test1", "1" }, - { "test2", 2 } - }; + var featureCollection = + JsonSerializer.Deserialize>(json); - var feature = new Text.Feature.Feature(geom, props); - model.Features.Add(feature); - } + Assert.IsNotNull(featureCollection); + Assert.IsNotNull(featureCollection.Features); + Assert.AreEqual(featureCollection.Features.Count, 3); + Assert.AreEqual("DD", featureCollection.Features.First().Properties.Name); + Assert.AreEqual(123, featureCollection.Features.First().Properties.Size); + } - var actualJson = JsonSerializer.Serialize(model); + [Test] + public void FeatureCollectionSerialization() + { + var model = new FeatureCollection(); + for (var i = 10; i-- > 0;) + { + var geom = new LineString(new[] + { + new Position(51.010, -1.034), + new Position(51.010, -0.034) + }); - Assert.IsNotNull(actualJson); + var props = new Dictionary + { + { "test1", "1" }, + { "test2", 2 } + }; - Assert.IsFalse(string.IsNullOrEmpty(actualJson)); + var feature = new Text.Feature.Feature(geom, props); + model.Features.Add(feature); } - [Test] - public void FeatureCollection_Equals_GetHashCode_Contract() - { - var left = GetFeatureCollection(); - var right = GetFeatureCollection(); + var actualJson = JsonSerializer.Serialize(model); - Assert_Are_Equal(left, right); - } + Assert.IsNotNull(actualJson); - [Test] - public void Serialized_And_Deserialized_FeatureCollection_Equals_And_Share_HashCode() - { - var leftFc = GetFeatureCollection(); - var leftJson = JsonSerializer.Serialize(leftFc); - var left = JsonSerializer.Deserialize(leftJson); + Assert.IsFalse(string.IsNullOrEmpty(actualJson)); + } - var rightFc = GetFeatureCollection(); - var rightJson = JsonSerializer.Serialize(rightFc); - var right = JsonSerializer.Deserialize(rightJson); + [Test] + public void FeatureCollection_Equals_GetHashCode_Contract() + { + var left = GetFeatureCollection(); + var right = GetFeatureCollection(); - Assert_Are_Equal(left, right); - } + Assert_Are_Equal(left, right); + } - [Test] - public void FeatureCollection_Test_IndexOf() - { - var model = new FeatureCollection(); - var expectedIds = new List(); - var expectedIndexes = new List(); + [Test] + public void Serialized_And_Deserialized_FeatureCollection_Equals_And_Share_HashCode() + { + var leftFc = GetFeatureCollection(); + var leftJson = JsonSerializer.Serialize(leftFc); + var left = JsonSerializer.Deserialize(leftJson); - for (var i = 0; i < 10; i++) - { - var id = "id" + i; + var rightFc = GetFeatureCollection(); + var rightJson = JsonSerializer.Serialize(rightFc); + var right = JsonSerializer.Deserialize(rightJson); - expectedIds.Add(id); - expectedIndexes.Add(i); + Assert_Are_Equal(left, right); + } - var geom = new LineString(new[] - { - new Position(51.010, -1.034), - new Position(51.010, -0.034) - }); + [Test] + public void FeatureCollection_Test_IndexOf() + { + var model = new FeatureCollection(); + var expectedIds = new List(); + var expectedIndexes = new List(); - var props = FeatureTests.GetPropertiesInRandomOrder(); + for (var i = 0; i < 10; i++) + { + var id = "id" + i; - var feature = new Text.Feature.Feature(geom, props, id); - model.Features.Add(feature); - } + expectedIds.Add(id); + expectedIndexes.Add(i); - for (var i = 0; i < 10; i++) + var geom = new LineString(new[] { - var actualFeature = model.Features[i]; - var actualId = actualFeature.Id; - var actualIndex = model.Features.IndexOf(actualFeature); + new Position(51.010, -1.034), + new Position(51.010, -0.034) + }); + + var props = FeatureTests.GetPropertiesInRandomOrder(); - var expectedId = expectedIds[i]; - var expectedIndex = expectedIndexes[i]; + var feature = new Text.Feature.Feature(geom, props, id); + model.Features.Add(feature); + } - Assert.AreEqual(expectedId, actualId); - Assert.AreEqual(expectedIndex, actualIndex); + for (var i = 0; i < 10; i++) + { + var actualFeature = model.Features[i]; + var actualId = actualFeature.Id; + var actualIndex = model.Features.IndexOf(actualFeature); - Assert.Inconclusive("not supported. the Feature.Id is optional. " + - " create a new class that inherits from" + - " Feature and then override Equals and GetHashCode"); + var expectedId = expectedIds[i]; + var expectedIndex = expectedIndexes[i]; - } + Assert.AreEqual(expectedId, actualId); + Assert.AreEqual(expectedIndex, actualIndex); + Assert.Inconclusive("not supported. the Feature.Id is optional. " + + " create a new class that inherits from" + + " Feature and then override Equals and GetHashCode"); } + } - private FeatureCollection GetFeatureCollection() + private FeatureCollection GetFeatureCollection() + { + var model = new FeatureCollection(); + for (var i = 10; i-- > 0;) { - var model = new FeatureCollection(); - for (var i = 10; i-- > 0;) + var geom = new LineString(new[] { - var geom = new LineString(new[] - { - new Position(51.010, -1.034), - new Position(51.010, -0.034) - }); - - var props = FeatureTests.GetPropertiesInRandomOrder(); - - var feature = new Text.Feature.Feature(geom, props); - model.Features.Add(feature); - } - return model; + new Position(51.010, -1.034), + new Position(51.010, -0.034) + }); + + var props = FeatureTests.GetPropertiesInRandomOrder(); + + var feature = new Text.Feature.Feature(geom, props); + model.Features.Add(feature); } - private void Assert_Are_Equal(FeatureCollection left, FeatureCollection right) - { - Assert.AreEqual(left, right); + return model; + } - Assert.IsTrue(left.Equals(right)); - Assert.IsTrue(right.Equals(left)); + private void Assert_Are_Equal(FeatureCollection left, FeatureCollection right) + { + Assert.AreEqual(left, right); - Assert.IsTrue(left.Equals(left)); - Assert.IsTrue(right.Equals(right)); + Assert.IsTrue(left.Equals(right)); + Assert.IsTrue(right.Equals(left)); - Assert.IsTrue(left == right); - Assert.IsTrue(right == left); + Assert.IsTrue(left.Equals(left)); + Assert.IsTrue(right.Equals(right)); - Assert.IsFalse(left != right); - Assert.IsFalse(right != left); + Assert.IsTrue(left == right); + Assert.IsTrue(right == left); - Assert.AreEqual(left.GetHashCode(), right.GetHashCode()); - } + Assert.IsFalse(left != right); + Assert.IsFalse(right != left); + + Assert.AreEqual(left.GetHashCode(), right.GetHashCode()); + } + + private class FeatureCollectionTestPropertyObject + { + public string Name { get; set; } + public int Size { get; set; } } } \ No newline at end of file diff --git a/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests_Can_DeserializeGeneric.json b/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests_Can_DeserializeGeneric.json new file mode 100644 index 0000000..98b23ca --- /dev/null +++ b/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests_Can_DeserializeGeneric.json @@ -0,0 +1,76 @@ +{ + "type": "FeatureCollection", + "features": [{ + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [102.0, 0.5] + }, + "properties": { + "name": "DD", + "size": 123 + } + }, { + "type": "Feature", + "properties": { + "name": "DD", + "size": 123 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [-3.124469107867639, 56.43179349026641], + [-3.181864056758185, 56.50435867827879], + [-3.080807472497396, 56.58041883184697], + [-3.204635351704243, 56.66878970099241], + [-3.153385207792676, 56.750141153246226], + [-3.300369428804113, 56.8589226202768], + [-3.20971234483721, 56.947300739465064], + [-3.064462793503021, 56.91976858406769], + [-2.972112587880359, 56.97746168167823], + [-2.854882511931398, 56.98360267279684], + [-2.680251743133697, 56.945352112881636], + [-2.615357138064907, 56.78566372854147], + [-2.493780338741513, 56.76540172907848], + [-2.315459650038894, 56.87577071411662], + [-2.224180437247053, 56.88745481725907], + [-2.309193985939006, 56.80497206404891], + [-2.410860986028102, 56.768333064132314], + [-2.551721986204847, 56.560417064546556], + [-2.719166986355991, 56.49336106469278], + [-3.124469107867639, 56.43179349026641] + ] + ], + [ + [ + [-2.818223720652239, 56.423668560365314], + [-2.975782222542367, 56.380750980197035], + [-3.063948244048636, 56.392897691447075], + [-2.921693986527472, 56.452056064793695], + [-2.818223720652239, 56.423668560365314] + ] + ] + ] + } + }, { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [100.0, 0.0], + [101.0, 0.0], + [101.0, 1.0], + [100.0, 1.0], + [100.0, 0.0] + ] + ] + }, + "properties": { + "name": "DD", + "size": 123 + } + }] +} \ No newline at end of file diff --git a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj index d2ce97c..98b0210 100644 --- a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj +++ b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj @@ -4,11 +4,13 @@ {6C93B314-9208-4684-B873-172F7EC81689} GeoJSON.Text.Tests GeoJSON.Text.Tests - net462;netcoreapp3.1;net5;net6 + net462,net6.0;net7.0;netcoreapp3.1 false + 10 + @@ -34,6 +36,7 @@ + diff --git a/src/GeoJSON.Text/Feature/FeatureCollection.cs b/src/GeoJSON.Text/Feature/FeatureCollection.cs index 15923a3..f724c95 100644 --- a/src/GeoJSON.Text/Feature/FeatureCollection.cs +++ b/src/GeoJSON.Text/Feature/FeatureCollection.cs @@ -5,123 +5,245 @@ using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; +using GeoJSON.Text.Geometry; -namespace GeoJSON.Text.Feature +namespace GeoJSON.Text.Feature; + +/// +/// Defines the FeatureCollection type. +/// +public class FeatureCollection : GeoJSONObject, IEqualityComparer, IEquatable { /// - /// Defines the FeatureCollection type. + /// Initializes a new instance of the class. /// - public class FeatureCollection : GeoJSONObject, IEqualityComparer, IEquatable + public FeatureCollection() : this(new List()) { - /// - /// Initializes a new instance of the class. - /// - public FeatureCollection() : this(new List()) + } + + /// + /// Initializes a new instance of the class. + /// + /// The features. + public FeatureCollection(List features) + { + if (features == null) { + throw new ArgumentNullException(nameof(features)); } - /// - /// Initializes a new instance of the class. - /// - /// The features. - public FeatureCollection(List features) + Features = features; + } + + [JsonPropertyName("type")] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [JsonConverter(typeof(JsonStringEnumConverter))] + public override GeoJSONObjectType Type => GeoJSONObjectType.FeatureCollection; + + /// + /// Gets the features. + /// + /// The features. + [JsonPropertyName("features")] + //[JsonConverter(typeof(FeatureEnumerableConverter))] + public List Features { get; set; } + + #region IEqualityComparer, IEquatable + + /// + /// Determines whether the specified object is equal to the current object + /// + public override bool Equals(object obj) + { + return Equals(this, obj as FeatureCollection); + } + + /// + /// Determines whether the specified object is equal to the current object + /// + public bool Equals(FeatureCollection other) + { + return Equals(this, other); + } + + /// + /// Determines whether the specified object instances are considered equal + /// + public bool Equals(FeatureCollection left, FeatureCollection right) + { + if (base.Equals(left, right)) { - if (features == null) - { - throw new ArgumentNullException(nameof(features)); - } + return left.Features.SequenceEqual(right.Features); + } + + return false; + } - Features = features; + /// + /// Determines whether the specified object instances are considered equal + /// + public static bool operator ==(FeatureCollection left, FeatureCollection right) + { + if (ReferenceEquals(left, right)) + { + return true; } - [JsonPropertyName("type")] - [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] - public override GeoJSONObjectType Type => GeoJSONObjectType.FeatureCollection; - - /// - /// Gets the features. - /// - /// The features. - [JsonPropertyName("features")] - //[JsonConverter(typeof(FeatureEnumerableConverter))] - public List Features { get; set; } - - #region IEqualityComparer, IEquatable - - /// - /// Determines whether the specified object is equal to the current object - /// - public override bool Equals(object obj) + if (ReferenceEquals(null, right)) { - return Equals(this, obj as FeatureCollection); + return false; } - /// - /// Determines whether the specified object is equal to the current object - /// - public bool Equals(FeatureCollection other) + return left != null && left.Equals(right); + } + + /// + /// Determines whether the specified object instances are not considered equal + /// + public static bool operator !=(FeatureCollection left, FeatureCollection right) + { + return !(left == right); + } + + /// + /// Returns the hash code for this instance + /// + public override int GetHashCode() + { + int hash = base.GetHashCode(); + foreach (var feature in Features) { - return Equals(this, other); + hash = (hash * 397) ^ feature.GetHashCode(); } - /// - /// Determines whether the specified object instances are considered equal - /// - public bool Equals(FeatureCollection left, FeatureCollection right) + return hash; + } + + /// + /// Returns the hash code for the specified object + /// + public int GetHashCode(FeatureCollection other) + { + return other.GetHashCode(); + } + + #endregion +} + +public class FeatureCollection : FeatureCollection, IEqualityComparer>, + IEquatable> +{ + /// + /// Initializes a new instance of the class. + /// + public FeatureCollection() : this(new List>()) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The features. + public FeatureCollection(List> features) + { + if (features == null) { - if (base.Equals(left, right)) - { - return left.Features.SequenceEqual(right.Features); - } - return false; + throw new ArgumentNullException(nameof(features)); } - /// - /// Determines whether the specified object instances are considered equal - /// - public static bool operator ==(FeatureCollection left, FeatureCollection right) + Features = features; + } + + [JsonPropertyName("type")] + [JsonIgnore(Condition = JsonIgnoreCondition.Never)] + [JsonConverter(typeof(JsonStringEnumConverter))] + public override GeoJSONObjectType Type => GeoJSONObjectType.FeatureCollection; + + /// + /// Gets the features. + /// + /// The features. + [JsonPropertyName("features")] + new public List> Features { get; private set; } + + #region IEqualityComparer, IEquatable + + /// + /// Determines whether the specified object is equal to the current object + /// + public override bool Equals(object obj) + { + return Equals(this, obj as FeatureCollection); + } + + /// + /// Determines whether the specified object is equal to the current object + /// + public bool Equals(FeatureCollection other) + { + return Equals(this, other); + } + + /// + /// Determines whether the specified object instances are considered equal + /// + public bool Equals(FeatureCollection left, FeatureCollection right) + { + if (base.Equals(left, right)) { - if (ReferenceEquals(left, right)) - { - return true; - } - if (ReferenceEquals(null, right)) - { - return false; - } - return left != null && left.Equals(right); + return left.Features.SequenceEqual(right.Features); } - /// - /// Determines whether the specified object instances are not considered equal - /// - public static bool operator !=(FeatureCollection left, FeatureCollection right) + return false; + } + + /// + /// Determines whether the specified object instances are considered equal + /// + public static bool operator ==(FeatureCollection left, FeatureCollection right) + { + if (ReferenceEquals(left, right)) { - return !(left == right); + return true; } - /// - /// Returns the hash code for this instance - /// - public override int GetHashCode() + if (ReferenceEquals(null, right)) { - int hash = base.GetHashCode(); - foreach (var feature in Features) - { - hash = (hash * 397) ^ feature.GetHashCode(); - } - return hash; + return false; } - /// - /// Returns the hash code for the specified object - /// - public int GetHashCode(FeatureCollection other) + return left != null && left.Equals(right); + } + + /// + /// Determines whether the specified object instances are not considered equal + /// + public static bool operator !=(FeatureCollection left, FeatureCollection right) + { + return !(left == right); + } + + /// + /// Returns the hash code for this instance + /// + public override int GetHashCode() + { + int hash = base.GetHashCode(); + foreach (var feature in Features) { - return other.GetHashCode(); + hash = (hash * 397) ^ feature.GetHashCode(); } - #endregion + return hash; } -} \ No newline at end of file + + /// + /// Returns the hash code for the specified object + /// + public int GetHashCode(FeatureCollection other) + { + return other.GetHashCode(); + } + + #endregion +} diff --git a/src/GeoJSON.Text/GeoJSON.Text.csproj b/src/GeoJSON.Text/GeoJSON.Text.csproj index a5e31a1..e52fa1e 100644 --- a/src/GeoJSON.Text/GeoJSON.Text.csproj +++ b/src/GeoJSON.Text/GeoJSON.Text.csproj @@ -1,8 +1,8 @@  - netstandard2.0 - Latest + net6.0;net7.0;netstandard2.0 + 10 .Net types for the GeoJSON RFC to be used with System.Text.Json Matt Hunt GeoJSON.Text @@ -14,9 +14,7 @@ git geojson;geo;json;geolocation MIT - true - true snupkg true @@ -24,7 +22,6 @@ true ../key.snk false - From 31ec322c320a24fdb7136620de81812fc28aaeb3 Mon Sep 17 00:00:00 2001 From: Matt Hunt Date: Tue, 2 May 2023 10:39:44 +0100 Subject: [PATCH 10/22] Adding .net 7 to build matrix --- .github/workflows/ci-build.yml | 1 + .github/workflows/continous-benchmark.yml | 1 + .github/workflows/release.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 0ff758d..8d3dd7f 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -33,6 +33,7 @@ jobs: 3.1.x 5.0.x 6.0.x + 7.0.x - name: Install dependencies run: dotnet restore src/${{ env.PROJECT_NAME }}.sln - name: Build solution diff --git a/.github/workflows/continous-benchmark.yml b/.github/workflows/continous-benchmark.yml index 6d60779..11e91f2 100644 --- a/.github/workflows/continous-benchmark.yml +++ b/.github/workflows/continous-benchmark.yml @@ -21,6 +21,7 @@ jobs: 3.1.x 5.0.x 6.0.x + 7.0.x # Run benchmark with `go test -bench` and stores the output to a file - name: Run benchmark run: dotnet run --project ./GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj --framework net6 --runtimes net60 -c Release -- --job medium -f *SerializeAndDeserialize* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4a22b78..0be7637 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,6 +43,7 @@ jobs: 3.1.x 5.0.x 6.0.x + 7.0.x - name: Install dependencies run: dotnet restore src/${{ env.PROJECT_NAME }}.sln - name: Build solution From 044a6ed4bc579f5934a422d5a6bac3240837ade0 Mon Sep 17 00:00:00 2001 From: Ankur Garg Date: Sun, 1 Oct 2023 23:00:24 -0400 Subject: [PATCH 11/22] Fixed the support for test projects. --- src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj index 98b0210..4aaddd3 100644 --- a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj +++ b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj @@ -4,7 +4,7 @@ {6C93B314-9208-4684-B873-172F7EC81689} GeoJSON.Text.Tests GeoJSON.Text.Tests - net462,net6.0;net7.0;netcoreapp3.1 + net6.0;net7.0;netstandard2.0 false 10 From fe2d55b5f2551ebd50be7a3615919fbd790dc6e7 Mon Sep 17 00:00:00 2001 From: Ankur Garg Date: Sun, 1 Oct 2023 23:15:49 -0400 Subject: [PATCH 12/22] Fixed tests. Private "set" was causing issue --- .../Feature/FeatureCollectionTests.cs | 8 ++++---- src/GeoJSON.Text/Feature/FeatureCollection.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs b/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs index 5e6d47e..c3116ab 100644 --- a/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs +++ b/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs @@ -46,8 +46,8 @@ public void Can_DeserializeGeneric() Assert.IsNotNull(featureCollection); Assert.IsNotNull(featureCollection.Features); Assert.AreEqual(featureCollection.Features.Count, 3); - Assert.AreEqual("DD", featureCollection.Features.First().Properties.Name); - Assert.AreEqual(123, featureCollection.Features.First().Properties.Size); + Assert.AreEqual("DD", featureCollection.Features.First().Properties.name); + Assert.AreEqual(123, featureCollection.Features.First().Properties.size); } [Test] @@ -188,7 +188,7 @@ private void Assert_Are_Equal(FeatureCollection left, FeatureCollection right) private class FeatureCollectionTestPropertyObject { - public string Name { get; set; } - public int Size { get; set; } + public string name { get; set; } + public int size { get; set; } } } \ No newline at end of file diff --git a/src/GeoJSON.Text/Feature/FeatureCollection.cs b/src/GeoJSON.Text/Feature/FeatureCollection.cs index f724c95..8caeefc 100644 --- a/src/GeoJSON.Text/Feature/FeatureCollection.cs +++ b/src/GeoJSON.Text/Feature/FeatureCollection.cs @@ -164,7 +164,7 @@ public FeatureCollection(List> features) /// /// The features. [JsonPropertyName("features")] - new public List> Features { get; private set; } + public new List> Features { get; set; } #region IEqualityComparer, IEquatable From c76e812b8c0e4efb75a0f988b18df3126c91912a Mon Sep 17 00:00:00 2001 From: James Thompson Date: Sat, 20 Apr 2024 09:10:01 +1000 Subject: [PATCH 13/22] #24 Place conditions on STJ so only for net standard --- src/GeoJSON.Text/GeoJSON.Text.csproj | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/GeoJSON.Text/GeoJSON.Text.csproj b/src/GeoJSON.Text/GeoJSON.Text.csproj index e52fa1e..3b580a2 100644 --- a/src/GeoJSON.Text/GeoJSON.Text.csproj +++ b/src/GeoJSON.Text/GeoJSON.Text.csproj @@ -26,7 +26,7 @@ true - + @@ -34,6 +34,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + + From af9ab313bc0bbb96e2500a20e570b97b1fd8d506 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Sun, 27 Oct 2024 10:20:31 +0100 Subject: [PATCH 14/22] Update dependencies and target frameworks and fix build warnings --- .../GeoJSON.Text.Test.Benchmark.csproj | 9 ++++----- src/GeoJSON.Text.Test.Benchmark/TestConfig.cs | 6 +++--- .../GeoJSON.Text.Test.Unit.csproj | 15 +++++++-------- src/GeoJSON.Text/GeoJSON.Text.csproj | 12 ++++-------- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj b/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj index 8aefd83..1135353 100644 --- a/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj +++ b/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj @@ -1,11 +1,10 @@  - net6.0;net7.0;netstandard2.0 + net6.0;net8.0 disable enable False - 10 @@ -27,9 +26,9 @@ - - - + + + diff --git a/src/GeoJSON.Text.Test.Benchmark/TestConfig.cs b/src/GeoJSON.Text.Test.Benchmark/TestConfig.cs index 8c0324b..4ba45b5 100644 --- a/src/GeoJSON.Text.Test.Benchmark/TestConfig.cs +++ b/src/GeoJSON.Text.Test.Benchmark/TestConfig.cs @@ -33,7 +33,7 @@ public TestConfig() private class FastestToSlowestOrderer : IOrderer { - public IEnumerable GetExecutionOrder(ImmutableArray benchmarksCase) => + public IEnumerable GetExecutionOrder(ImmutableArray benchmarksCase, IEnumerable? order = null) => from benchmark in benchmarksCase orderby benchmark.Parameters["X"] descending, benchmark.Descriptor.WorkloadMethodDisplayInfo @@ -44,13 +44,13 @@ from benchmark in benchmarksCase public string GetLogicalGroupKey(ImmutableArray allBenchmarksCases, BenchmarkCase benchmarkCase) => benchmarkCase.Job.DisplayInfo + "_" + benchmarkCase.Parameters.DisplayInfo; - public IEnumerable> GetLogicalGroupOrder(IEnumerable> logicalGroups) => + public IEnumerable> GetLogicalGroupOrder(IEnumerable> logicalGroups, IEnumerable? order = null) => logicalGroups.OrderBy(it => it.Key); public IEnumerable GetSummaryOrder(ImmutableArray benchmarksCases, Summary summary) { var benchmarkResult = from benchmark in benchmarksCases - orderby summary[benchmark].ResultStatistics.Mean + orderby summary[benchmark]?.ResultStatistics?.Mean ?? 0 select benchmark; return benchmarkResult; diff --git a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj index 4aaddd3..8b52673 100644 --- a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj +++ b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj @@ -4,9 +4,8 @@ {6C93B314-9208-4684-B873-172F7EC81689} GeoJSON.Text.Tests GeoJSON.Text.Tests - net6.0;net7.0;netstandard2.0 + net6.0;net8.0 false - 10 @@ -61,18 +60,18 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + diff --git a/src/GeoJSON.Text/GeoJSON.Text.csproj b/src/GeoJSON.Text/GeoJSON.Text.csproj index 3b580a2..bed1fa6 100644 --- a/src/GeoJSON.Text/GeoJSON.Text.csproj +++ b/src/GeoJSON.Text/GeoJSON.Text.csproj @@ -1,7 +1,7 @@  - net6.0;net7.0;netstandard2.0 + net6.0;net8.0;netstandard2.0 10 .Net types for the GeoJSON RFC to be used with System.Text.Json Matt Hunt @@ -29,15 +29,11 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + - - + + \ No newline at end of file From 2f6a528ea11e1146053ca0adad0c9165d1262304 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Sun, 27 Oct 2024 10:20:31 +0100 Subject: [PATCH 15/22] Update GitHub actions and drop legacy .NET versions --- .github/workflows/ci-build.yml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 8d3dd7f..06fc27e 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -25,29 +25,27 @@ jobs: VSTEST_CONNECTION_TIMEOUT: 900 steps: - - uses: actions/checkout@v2 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: dotnet-version: | - 3.1.x - 5.0.x 6.0.x - 7.0.x + 8.0.x - name: Install dependencies run: dotnet restore src/${{ env.PROJECT_NAME }}.sln - name: Build solution run: dotnet build src/${{ env.PROJECT_NAME }}.sln -c Release --no-restore - name: Test run: dotnet test src/${{ env.PROJECT_NAME }}.sln -c Release --no-build /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=../coverage/ - - uses: codecov/codecov-action@v2 + - uses: codecov/codecov-action@v4 if: github.ref == 'refs/heads/main' with: token: ${{ secrets.CODECOV_TOKEN }} directory: src/coverage flags: unittests - name: Upload Artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: nupkg path: src/${{ env.PROJECT_NAME }}/bin/Release/*.nupkg From 1da5537eb0fe03efdad065699905b2f64091c362 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Mon, 28 Oct 2024 17:49:54 +0100 Subject: [PATCH 16/22] fix Benchmark --- .github/workflows/continous-benchmark.yml | 15 ++++++--------- .../GeoJSON.Text.Test.Benchmark.csproj | 3 ++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/continous-benchmark.yml b/.github/workflows/continous-benchmark.yml index 11e91f2..9b84a0e 100644 --- a/.github/workflows/continous-benchmark.yml +++ b/.github/workflows/continous-benchmark.yml @@ -13,21 +13,18 @@ jobs: working-directory: ./src steps: - - uses: actions/checkout@v2 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: dotnet-version: | - 3.1.x - 5.0.x - 6.0.x - 7.0.x + 8.0.x # Run benchmark with `go test -bench` and stores the output to a file - name: Run benchmark - run: dotnet run --project ./GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj --framework net6 --runtimes net60 -c Release -- --job medium -f *SerializeAndDeserialize* + run: dotnet run --project ./GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj -c Release -- --job medium -f *SerializeAndDeserialize* # Download previous benchmark result from cache (if exists) - name: Download previous benchmark data - uses: actions/cache@v1 + uses: actions/cache@v4 with: path: ./cache key: ${{ runner.os }}-benchmark diff --git a/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj b/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj index 1135353..2c8a0ed 100644 --- a/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj +++ b/src/GeoJSON.Text.Test.Benchmark/GeoJSON.Text.Test.Benchmark.csproj @@ -1,7 +1,8 @@  - net6.0;net8.0 + net8.0 + Exe disable enable False From f2145acfd7a3857248d5a050ac66df444b20f149 Mon Sep 17 00:00:00 2001 From: Xavier Fischer Date: Mon, 4 Nov 2024 23:29:04 +0100 Subject: [PATCH 17/22] bump version to 1.1.0, contributors --- src/GeoJSON.Text/GeoJSON.Text.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GeoJSON.Text/GeoJSON.Text.csproj b/src/GeoJSON.Text/GeoJSON.Text.csproj index bed1fa6..a86daab 100644 --- a/src/GeoJSON.Text/GeoJSON.Text.csproj +++ b/src/GeoJSON.Text/GeoJSON.Text.csproj @@ -4,11 +4,11 @@ net6.0;net8.0;netstandard2.0 10 .Net types for the GeoJSON RFC to be used with System.Text.Json - Matt Hunt + Matt Hunt and Contributors GeoJSON.Text - Copyright © Matt Hunt and Contributors, 2014 - 2021 + Copyright © Matt Hunt and Contributors, 2014 - 2024 true - 0.1.0 + 1.1.0 https://github.com/GeoJSON-Net/GeoJSON.Text https://github.com/GeoJSON-Net/GeoJSON.Text.git git From 44366de9845f222f84850db0cd3037ea85bab56e Mon Sep 17 00:00:00 2001 From: Xavier Fischer Date: Mon, 4 Nov 2024 23:49:31 +0100 Subject: [PATCH 18/22] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2667bd2..cfeb781 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build and Test](https://github.com/GeoJSON-Net/GeoJSON.Text/actions/workflows/ci-build.yml/badge.svg?branch=main)](https://github.com/GeoJSON-Net/GeoJSON.Text/actions/workflows/ci-build.yml) [![codecov](https://codecov.io/gh/GeoJSON-Net/GeoJSON.Text/branch/main/graph/badge.svg?token=SE9XY1T8XO)](https://codecov.io/gh/GeoJSON-Net/GeoJSON.Text) +[![NuGet Version](http://img.shields.io/nuget/v/GeoJSON.Text.svg?style=flat)](https://www.nuget.org/packages/GeoJSON.Text/) [![Build and Test](https://github.com/GeoJSON-Net/GeoJSON.Text/actions/workflows/ci-build.yml/badge.svg?branch=main)](https://github.com/GeoJSON-Net/GeoJSON.Text/actions/workflows/ci-build.yml) [![codecov](https://codecov.io/gh/GeoJSON-Net/GeoJSON.Text/branch/main/graph/badge.svg?token=SE9XY1T8XO)](https://codecov.io/gh/GeoJSON-Net/GeoJSON.Text) # GeoJSON.Text GeoJSON.Text is a .NET library for the [RFC 7946 The GeoJSON Format](https://tools.ietf.org/html/rfc7946) and it uses and provides [System.Text.Json](https://docs.microsoft.com/en-us/dotnet/api/system.text.json?view=net-6.0) converters for serialization and deserialization of GeoJSON data. From aa13a7534acc3117e398526384b04cbb9c396c13 Mon Sep 17 00:00:00 2001 From: Captainpast Date: Wed, 19 Feb 2025 18:01:15 +0100 Subject: [PATCH 19/22] using generic JsonStringEnumConverter for net8.0 --- src/GeoJSON.Text/Feature/Feature.cs | 1 - src/GeoJSON.Text/Feature/FeatureCollection.cs | 2 -- src/GeoJSON.Text/GeoJSONObject.cs | 1 - src/GeoJSON.Text/GeoJSONObjectType.cs | 6 ++++++ src/GeoJSON.Text/Geometry/GeometryCollection.cs | 1 - src/GeoJSON.Text/Geometry/IGeometryObject.cs | 1 - src/GeoJSON.Text/Geometry/LineString.cs | 1 - src/GeoJSON.Text/Geometry/MultiLineString.cs | 1 - src/GeoJSON.Text/Geometry/MultiPoint.cs | 1 - src/GeoJSON.Text/Geometry/MultiPolygon.cs | 1 - src/GeoJSON.Text/Geometry/Point.cs | 1 - src/GeoJSON.Text/Geometry/Polygon.cs | 1 - 12 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/GeoJSON.Text/Feature/Feature.cs b/src/GeoJSON.Text/Feature/Feature.cs index 5568519..ba4d2bd 100644 --- a/src/GeoJSON.Text/Feature/Feature.cs +++ b/src/GeoJSON.Text/Feature/Feature.cs @@ -49,7 +49,6 @@ public Feature(IGeometryObject geometry, TProps properties, string id = null) [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.Feature; [JsonPropertyName( "id")] diff --git a/src/GeoJSON.Text/Feature/FeatureCollection.cs b/src/GeoJSON.Text/Feature/FeatureCollection.cs index 8caeefc..2e1243e 100644 --- a/src/GeoJSON.Text/Feature/FeatureCollection.cs +++ b/src/GeoJSON.Text/Feature/FeatureCollection.cs @@ -37,7 +37,6 @@ public FeatureCollection(List features) [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.FeatureCollection; /// @@ -156,7 +155,6 @@ public FeatureCollection(List> features) [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.FeatureCollection; /// diff --git a/src/GeoJSON.Text/GeoJSONObject.cs b/src/GeoJSON.Text/GeoJSONObject.cs index 2e69d81..8adf906 100644 --- a/src/GeoJSON.Text/GeoJSONObject.cs +++ b/src/GeoJSON.Text/GeoJSONObject.cs @@ -55,7 +55,6 @@ public abstract class GeoJSONObject : IGeoJSONObject, IEqualityComparer [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public abstract GeoJSONObjectType Type { get; } diff --git a/src/GeoJSON.Text/GeoJSONObjectType.cs b/src/GeoJSON.Text/GeoJSONObjectType.cs index ed3ae0e..b8d8582 100644 --- a/src/GeoJSON.Text/GeoJSONObjectType.cs +++ b/src/GeoJSON.Text/GeoJSONObjectType.cs @@ -1,12 +1,18 @@ // Copyright © Joerg Battermann 2014, Matt Hunt 2017 using System.Runtime.Serialization; +using System.Text.Json.Serialization; namespace GeoJSON.Text { /// /// Defines the GeoJSON Objects types. /// +#if NET8_0_OR_GREATER + [JsonConverter(typeof(JsonStringEnumConverter))] +#else + [JsonConverter(typeof(JsonStringEnumConverter))] +#endif public enum GeoJSONObjectType { /// diff --git a/src/GeoJSON.Text/Geometry/GeometryCollection.cs b/src/GeoJSON.Text/Geometry/GeometryCollection.cs index ee32cbb..3381eff 100644 --- a/src/GeoJSON.Text/Geometry/GeometryCollection.cs +++ b/src/GeoJSON.Text/Geometry/GeometryCollection.cs @@ -36,7 +36,6 @@ public GeometryCollection(IEnumerable geometries) [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.GeometryCollection; /// diff --git a/src/GeoJSON.Text/Geometry/IGeometryObject.cs b/src/GeoJSON.Text/Geometry/IGeometryObject.cs index 9fe7592..c757537 100644 --- a/src/GeoJSON.Text/Geometry/IGeometryObject.cs +++ b/src/GeoJSON.Text/Geometry/IGeometryObject.cs @@ -23,7 +23,6 @@ public interface IGeometryObject /// The type of the object. /// [JsonPropertyName("type")] - [JsonConverter(typeof(JsonStringEnumConverter))] GeoJSONObjectType Type { get; } } } diff --git a/src/GeoJSON.Text/Geometry/LineString.cs b/src/GeoJSON.Text/Geometry/LineString.cs index 1b17959..797b7ff 100644 --- a/src/GeoJSON.Text/Geometry/LineString.cs +++ b/src/GeoJSON.Text/Geometry/LineString.cs @@ -52,7 +52,6 @@ public LineString(IEnumerable coordinates) [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.LineString; /// diff --git a/src/GeoJSON.Text/Geometry/MultiLineString.cs b/src/GeoJSON.Text/Geometry/MultiLineString.cs index c33f99e..9b349a4 100644 --- a/src/GeoJSON.Text/Geometry/MultiLineString.cs +++ b/src/GeoJSON.Text/Geometry/MultiLineString.cs @@ -46,7 +46,6 @@ public MultiLineString(IEnumerable>> coordinates [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.MultiLineString; /// diff --git a/src/GeoJSON.Text/Geometry/MultiPoint.cs b/src/GeoJSON.Text/Geometry/MultiPoint.cs index cb97fe7..307fc04 100644 --- a/src/GeoJSON.Text/Geometry/MultiPoint.cs +++ b/src/GeoJSON.Text/Geometry/MultiPoint.cs @@ -40,7 +40,6 @@ public MultiPoint(IEnumerable> coordinates) [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.MultiPoint; /// diff --git a/src/GeoJSON.Text/Geometry/MultiPolygon.cs b/src/GeoJSON.Text/Geometry/MultiPolygon.cs index 3c9b261..66342a9 100644 --- a/src/GeoJSON.Text/Geometry/MultiPolygon.cs +++ b/src/GeoJSON.Text/Geometry/MultiPolygon.cs @@ -42,7 +42,6 @@ public MultiPolygon(IEnumerable>>> c [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.MultiPolygon; /// diff --git a/src/GeoJSON.Text/Geometry/Point.cs b/src/GeoJSON.Text/Geometry/Point.cs index 19724a0..7db90f9 100644 --- a/src/GeoJSON.Text/Geometry/Point.cs +++ b/src/GeoJSON.Text/Geometry/Point.cs @@ -31,7 +31,6 @@ public Point(IPosition coordinates) [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.Point; /// diff --git a/src/GeoJSON.Text/Geometry/Polygon.cs b/src/GeoJSON.Text/Geometry/Polygon.cs index 6c78a53..aa55cbc 100644 --- a/src/GeoJSON.Text/Geometry/Polygon.cs +++ b/src/GeoJSON.Text/Geometry/Polygon.cs @@ -57,7 +57,6 @@ public Polygon(IEnumerable>> coordinates) [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] - [JsonConverter(typeof(JsonStringEnumConverter))] public override GeoJSONObjectType Type => GeoJSONObjectType.Polygon; /// From a5e6693e9c0e6d5483a4dad35f8860e019bf1684 Mon Sep 17 00:00:00 2001 From: Captainpast Date: Wed, 19 Feb 2025 18:02:35 +0100 Subject: [PATCH 20/22] Define the type of CrsConverter --- src/GeoJSON.Text/Converters/CrsConverter.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/GeoJSON.Text/Converters/CrsConverter.cs b/src/GeoJSON.Text/Converters/CrsConverter.cs index 5fadd87..d4d8674 100644 --- a/src/GeoJSON.Text/Converters/CrsConverter.cs +++ b/src/GeoJSON.Text/Converters/CrsConverter.cs @@ -10,7 +10,7 @@ namespace GeoJSON.Text.Converters /// /// Converts types to and from JSON. /// - public class CrsConverter : JsonConverter + public class CrsConverter : JsonConverter { public override bool HandleNull => true; @@ -41,7 +41,7 @@ public override bool CanConvert(Type objectType) /// or /// CRS must have a "type" property /// - public override object Read( + public override ICRSObject Read( ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) @@ -106,7 +106,8 @@ public override object Read( } } - return new NotSupportedException(string.Format("Type {0} unexpected.", crsType)); + //return new NotSupportedException(string.Format("Type {0} unexpected.", crsType)); + return null; } /// @@ -118,7 +119,7 @@ public override object Read( /// public override void Write( Utf8JsonWriter writer, - object crsValue, + ICRSObject crsValue, JsonSerializerOptions options) { var value = (ICRSObject)crsValue; From 0ec813bb517d8c2e19faa084b296181db769cfea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Grafstr=C3=B6m?= Date: Fri, 28 Feb 2025 11:23:01 +0100 Subject: [PATCH 21/22] Handle null altitudes when reading positions --- .../GeoJSON.Text.Test.Unit.csproj | 4 + .../Geometry/LineStringTests.cs | 25 ++++++ ...ngTests_Can_Deserialize_With_Altitude.json | 9 ++ .../Converters/PositionConverter.cs | 85 +++++++++++++++++-- 4 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_With_Altitude.json diff --git a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj index 8b52673..4be94e0 100644 --- a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj +++ b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj @@ -22,6 +22,7 @@ + @@ -76,6 +77,9 @@ + + + Always diff --git a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs index 0f77d8a..2855a2c 100644 --- a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs +++ b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs @@ -83,6 +83,31 @@ public void Can_Deserialize() Assert.AreEqual(expectedLineString.Coordinates[0].Longitude, actualLineString.Coordinates[0].Longitude); } + [Test] + public void Can_Deserialize_With_Altitude() + { + var coordinates = new List + { + new Position(52.370725881211314, 4.889259338378906, 10.0), + new Position(52.3711451105601, 4.895267486572266, 10.5), + new Position(52.36931095278263, 4.892091751098633, null), + new Position(52.370725881211314, 4.889259338378906, 10.2) + }; + + var expectedLineString = new LineString(coordinates); + + var json = GetExpectedJson(); + var actualLineString = JsonSerializer.Deserialize(json); + + Assert.AreEqual(expectedLineString, actualLineString); + + Assert.AreEqual(4, actualLineString.Coordinates.Count); + Assert.AreEqual(expectedLineString.Coordinates[0].Latitude, actualLineString.Coordinates[0].Latitude); + Assert.AreEqual(expectedLineString.Coordinates[0].Longitude, actualLineString.Coordinates[0].Longitude); + Assert.AreEqual(expectedLineString.Coordinates[0].Altitude, actualLineString.Coordinates[0].Altitude); + Assert.AreEqual(expectedLineString.Coordinates[2].Altitude, actualLineString.Coordinates[2].Altitude); + } + [Test] public void Constructor_No_Coordinates_Throws_Exception() { diff --git a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_With_Altitude.json b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_With_Altitude.json new file mode 100644 index 0000000..f0ed4f0 --- /dev/null +++ b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_With_Altitude.json @@ -0,0 +1,9 @@ +{ + "coordinates": [ + [4.8892593383789062, 52.370725881211314, 10.0], + [4.8952674865722656, 52.3711451105601, 10.5], + [4.8920917510986328, 52.369310952782627, null], + [4.8892593383789062, 52.370725881211314, 10.2] + ], + "type": "LineString" +} \ No newline at end of file diff --git a/src/GeoJSON.Text/Converters/PositionConverter.cs b/src/GeoJSON.Text/Converters/PositionConverter.cs index 58abb40..0ab9947 100644 --- a/src/GeoJSON.Text/Converters/PositionConverter.cs +++ b/src/GeoJSON.Text/Converters/PositionConverter.cs @@ -2,6 +2,7 @@ using GeoJSON.Text.Geometry; using System; +using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; @@ -28,10 +29,9 @@ public override bool CanConvert(Type objectType) /// /// Reads the JSON representation of the object. /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. + /// The to read from. + /// Type of the object. + /// Serializer options. /// /// The object value. /// @@ -40,17 +40,84 @@ public override IPosition Read( Type type, JsonSerializerOptions options) { - double[] coordinates; - try - { - coordinates = JsonSerializer.Deserialize(ref reader, options); + { + if (reader.TokenType != JsonTokenType.StartArray) + { + throw new ArgumentException("Expected start of array"); + } + + double lng, lat; + double? alt; + + // Read longitude + if (!reader.Read()) + { + throw new ArgumentException("Expected number, but got end of data"); + } + if (reader.TokenType == JsonTokenType.EndArray) + { + throw new ArgumentException("Expected 2 or 3 coordinates but got 0"); + } + if (reader.TokenType != JsonTokenType.Number) + { + throw new ArgumentException("Expected number but got other type"); + } + lng = reader.GetDouble(); + + // Read latitude + if (!reader.Read()) + { + throw new ArgumentException("Expected number, but got end of data"); + } + if (reader.TokenType == JsonTokenType.EndArray) + { + throw new ArgumentException("Expected 2 or 3 coordinates but got 1"); + } + if (reader.TokenType != JsonTokenType.Number) + { + throw new ArgumentException("Expected number but got other type"); + } + lat = reader.GetDouble(); + + // Read altitude, or return if end of array is found + if (!reader.Read()) + { + throw new ArgumentException("Unexpected end of data"); + } + if (reader.TokenType == JsonTokenType.EndArray) + { + return new Position(lat, lng); + } + else if (reader.TokenType == JsonTokenType.Null) + { + alt = null; + } + else if (reader.TokenType == JsonTokenType.Number) + { + alt = reader.GetDouble(); + } + else + { + throw new ArgumentException("Expected number but got other type"); + } + + // Check what comes next. Expects end of array. + if (!reader.Read()) + { + throw new ArgumentException("Expected end of array, but got end of data"); + } + if (reader.TokenType != JsonTokenType.EndArray) + { + throw new ArgumentException("Expected 2 or 3 coordinates but got >= 4"); + } + + return new Position(lat, lng, alt); } catch (Exception e) { throw new JsonException("Error parsing coordinates", e); } - return coordinates?.ToPosition() ?? throw new JsonException("Coordinates cannot be null"); } /// From e51f9b56e94b28d2db304b07f4606955934c4491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Grafstr=C3=B6m?= Date: Fri, 28 Feb 2025 13:41:59 +0100 Subject: [PATCH 22/22] Restore support for serializer options when reading positions --- .../GeoJSON.Text.Test.Unit.csproj | 4 ++ .../Geometry/LineStringTests.cs | 52 +++++++++++++++++++ ...Tests_Can_Deserialize_String_Literals.json | 9 ++++ ...neStringTests_Can_Deserialize_Strings.json | 9 ++++ .../Converters/PositionConverter.cs | 30 +++++++++-- .../DoubleTenDecimalPlaceComparer.cs | 5 +- 6 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_String_Literals.json create mode 100644 src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_Strings.json diff --git a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj index 4be94e0..af09af1 100644 --- a/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj +++ b/src/GeoJSON.Text.Test.Unit/GeoJSON.Text.Test.Unit.csproj @@ -22,6 +22,8 @@ + + @@ -49,6 +51,8 @@ + + diff --git a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs index 2855a2c..63d9b56 100644 --- a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs +++ b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs @@ -83,6 +83,30 @@ public void Can_Deserialize() Assert.AreEqual(expectedLineString.Coordinates[0].Longitude, actualLineString.Coordinates[0].Longitude); } + [Test] + public void Can_Deserialize_Strings() + { + var coordinates = new List + { + new Position(52.370725881211314, 4.889259338378906), + new Position(52.3711451105601, 4.895267486572266), + new Position(52.36931095278263, 4.892091751098633), + new Position(52.370725881211314, 4.889259338378906) + }; + + var expectedLineString = new LineString(coordinates); + + var json = GetExpectedJson(); + var options = new JsonSerializerOptions { NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString }; + var actualLineString = JsonSerializer.Deserialize(json, options); + + Assert.AreEqual(expectedLineString, actualLineString); + + Assert.AreEqual(4, actualLineString.Coordinates.Count); + Assert.AreEqual(expectedLineString.Coordinates[0].Latitude, actualLineString.Coordinates[0].Latitude); + Assert.AreEqual(expectedLineString.Coordinates[0].Longitude, actualLineString.Coordinates[0].Longitude); + } + [Test] public void Can_Deserialize_With_Altitude() { @@ -108,6 +132,34 @@ public void Can_Deserialize_With_Altitude() Assert.AreEqual(expectedLineString.Coordinates[2].Altitude, actualLineString.Coordinates[2].Altitude); } + [Test] + public void Can_Deserialize_String_Literals() + { + var coordinates = new List + { + new Position(52.370725881211314, 4.889259338378906, double.NegativeInfinity), + new Position(52.3711451105601, 4.895267486572266, double.PositiveInfinity), + new Position(52.36931095278263, 4.892091751098633, double.NaN), + new Position(52.370725881211314, 4.889259338378906, double.NegativeInfinity) + }; + + var expectedLineString = new LineString(coordinates); + + var json = GetExpectedJson(); + var options = new JsonSerializerOptions { NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals }; + var actualLineString = JsonSerializer.Deserialize(json, options); + + bool b = expectedLineString.Coordinates[0].Equals(actualLineString.Coordinates[0]); + Assert.AreEqual(expectedLineString, actualLineString); + + Assert.AreEqual(4, actualLineString.Coordinates.Count); + Assert.AreEqual(expectedLineString.Coordinates[0].Latitude, actualLineString.Coordinates[0].Latitude); + Assert.AreEqual(expectedLineString.Coordinates[0].Longitude, actualLineString.Coordinates[0].Longitude); + Assert.AreEqual(expectedLineString.Coordinates[0].Altitude, actualLineString.Coordinates[0].Altitude); + Assert.AreEqual(expectedLineString.Coordinates[1].Altitude, actualLineString.Coordinates[1].Altitude); + Assert.AreEqual(expectedLineString.Coordinates[2].Altitude, actualLineString.Coordinates[2].Altitude); + } + [Test] public void Constructor_No_Coordinates_Throws_Exception() { diff --git a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_String_Literals.json b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_String_Literals.json new file mode 100644 index 0000000..594d58f --- /dev/null +++ b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_String_Literals.json @@ -0,0 +1,9 @@ +{ + "coordinates": [ + [4.8892593383789062, 52.370725881211314, "-Infinity"], + [4.8952674865722656, 52.3711451105601, "Infinity"], + [4.8920917510986328, 52.369310952782627, "NaN"], + [4.8892593383789062, 52.370725881211314, "-Infinity"] + ], + "type": "LineString" +} \ No newline at end of file diff --git a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_Strings.json b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_Strings.json new file mode 100644 index 0000000..7c5a502 --- /dev/null +++ b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests_Can_Deserialize_Strings.json @@ -0,0 +1,9 @@ +{ + "coordinates": [ + ["4.8892593383789062", "52.370725881211314"], + ["4.8952674865722656", "52.3711451105601"], + ["4.8920917510986328", "52.369310952782627"], + ["4.8892593383789062", "52.370725881211314"] + ], + "type": "LineString" +} \ No newline at end of file diff --git a/src/GeoJSON.Text/Converters/PositionConverter.cs b/src/GeoJSON.Text/Converters/PositionConverter.cs index 0ab9947..995b8b9 100644 --- a/src/GeoJSON.Text/Converters/PositionConverter.cs +++ b/src/GeoJSON.Text/Converters/PositionConverter.cs @@ -55,30 +55,48 @@ public override IPosition Read( { throw new ArgumentException("Expected number, but got end of data"); } + if (reader.TokenType == JsonTokenType.EndArray) { throw new ArgumentException("Expected 2 or 3 coordinates but got 0"); } - if (reader.TokenType != JsonTokenType.Number) + + if (reader.TokenType == JsonTokenType.Number) + { + lng = reader.GetDouble(); + } + else if (reader.TokenType == JsonTokenType.String) + { + lng = JsonSerializer.Deserialize(ref reader, options); + } + else { throw new ArgumentException("Expected number but got other type"); } - lng = reader.GetDouble(); // Read latitude if (!reader.Read()) { throw new ArgumentException("Expected number, but got end of data"); } + if (reader.TokenType == JsonTokenType.EndArray) { throw new ArgumentException("Expected 2 or 3 coordinates but got 1"); } - if (reader.TokenType != JsonTokenType.Number) + + if (reader.TokenType == JsonTokenType.Number) + { + lat = reader.GetDouble(); + } + else if (reader.TokenType == JsonTokenType.String) + { + lat = JsonSerializer.Deserialize(ref reader, options); + } + else { throw new ArgumentException("Expected number but got other type"); } - lat = reader.GetDouble(); // Read altitude, or return if end of array is found if (!reader.Read()) @@ -97,6 +115,10 @@ public override IPosition Read( { alt = reader.GetDouble(); } + else if (reader.TokenType == JsonTokenType.String) + { + alt = JsonSerializer.Deserialize(ref reader, options); + } else { throw new ArgumentException("Expected number but got other type"); diff --git a/src/GeoJSON.Text/DoubleTenDecimalPlaceComparer.cs b/src/GeoJSON.Text/DoubleTenDecimalPlaceComparer.cs index dbe75c5..da7aec0 100644 --- a/src/GeoJSON.Text/DoubleTenDecimalPlaceComparer.cs +++ b/src/GeoJSON.Text/DoubleTenDecimalPlaceComparer.cs @@ -15,7 +15,10 @@ public class DoubleTenDecimalPlaceComparer : IEqualityComparer { public bool Equals(double x, double y) { - return Math.Abs(x - y) < 0.0000000001; + return (double.IsNaN(x) && double.IsNaN(y)) || + (double.IsInfinity(x) && double.IsInfinity(y)) || + (double.IsNegativeInfinity(x) && double.IsNegativeInfinity(y)) || + Math.Abs(x - y) < 0.0000000001; } public int GetHashCode(double obj)