diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 0ff758d..06fc27e 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -25,28 +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 + 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 diff --git a/.github/workflows/continous-benchmark.yml b/.github/workflows/continous-benchmark.yml index 6d60779..9b84a0e 100644 --- a/.github/workflows/continous-benchmark.yml +++ b/.github/workflows/continous-benchmark.yml @@ -13,20 +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 + 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/.github/workflows/release.yml b/.github/workflows/release.yml index 84d884f..0be7637 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: @@ -32,20 +43,12 @@ 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 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 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/${{ 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/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. 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..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,12 +1,11 @@  + net8.0 Exe - netstandard2.0;net5;net6 disable enable False - Latest @@ -28,9 +27,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/Feature/FeatureCollectionTests.cs b/src/GeoJSON.Text.Test.Unit/Feature/FeatureCollectionTests.cs index 3c6d6cf..c3116ab 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..af09af1 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,12 @@ {6C93B314-9208-4684-B873-172F7EC81689} GeoJSON.Text.Tests GeoJSON.Text.Tests - net462;netcoreapp3.1;net5;net6 + net6.0;net8.0 false + @@ -21,6 +22,9 @@ + + + @@ -34,6 +38,7 @@ + @@ -46,6 +51,8 @@ + + @@ -58,22 +65,25 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + + + + Always diff --git a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs index 0f77d8a..63d9b56 100644 --- a/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs +++ b/src/GeoJSON.Text.Test.Unit/Geometry/LineStringTests.cs @@ -83,6 +83,83 @@ 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() + { + 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 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.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.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}" 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; diff --git a/src/GeoJSON.Text/Converters/PositionConverter.cs b/src/GeoJSON.Text/Converters/PositionConverter.cs index fc78e4f..995b8b9 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,106 @@ public override IPosition Read( Type type, JsonSerializerOptions options) { - double[] coordinates; - try - { - coordinates = JsonSerializer.Deserialize(ref reader); + { + 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) + { + 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"); + } + + // 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) + { + 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"); + } + + // 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 if (reader.TokenType == JsonTokenType.String) + { + alt = JsonSerializer.Deserialize(ref reader, options); + } + 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"); } /// 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) 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 15923a3..2e1243e 100644 --- a/src/GeoJSON.Text/Feature/FeatureCollection.cs +++ b/src/GeoJSON.Text/Feature/FeatureCollection.cs @@ -5,123 +5,243 @@ 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)] + 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)] + public override GeoJSONObjectType Type => GeoJSONObjectType.FeatureCollection; + + /// + /// Gets the features. + /// + /// The features. + [JsonPropertyName("features")] + public new 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 (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..a86daab 100644 --- a/src/GeoJSON.Text/GeoJSON.Text.csproj +++ b/src/GeoJSON.Text/GeoJSON.Text.csproj @@ -1,22 +1,20 @@  - netstandard2.0 - Latest + 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 geojson;geo;json;geolocation MIT - true - true snupkg true @@ -24,20 +22,18 @@ true ../key.snk false - true - + - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + + + \ No newline at end of file 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 e7dd7dc..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 { /// @@ -15,7 +21,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.2 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "Point")] Point, /// @@ -24,7 +30,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.3 /// - [EnumMember(Value = "multipoint")] + [EnumMember(Value = "MultiPoint")] MultiPoint, /// @@ -33,7 +39,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.4 /// - [EnumMember(Value = "linestring")] + [EnumMember(Value = "LineString")] LineString, /// @@ -42,7 +48,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.5 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "MultiLineString")] MultiLineString, /// @@ -51,7 +57,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.6 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "Polygon")] Polygon, /// @@ -60,7 +66,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.7 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "MultiPolygon")] MultiPolygon, /// @@ -69,7 +75,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.1.8 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "GeometryCollection")] GeometryCollection, /// @@ -78,7 +84,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.2 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "Feature")] Feature, /// @@ -87,7 +93,7 @@ public enum GeoJSONObjectType /// /// See https://tools.ietf.org/html/rfc7946#section-3.3 /// - [EnumMember(Value = "point")] + [EnumMember(Value = "FeatureCollection")] FeatureCollection } } 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; ///