From c045cc9481ee9e2115f22183877088005afea108 Mon Sep 17 00:00:00 2001 From: Michael Helmling Date: Sun, 11 Jun 2017 15:49:34 +0200 Subject: [PATCH 1/7] Add generic Feature class --- src/GeoJSON.Net/Feature/Feature.cs | 82 ++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/GeoJSON.Net/Feature/Feature.cs b/src/GeoJSON.Net/Feature/Feature.cs index 77ed2181..37828a69 100644 --- a/src/GeoJSON.Net/Feature/Feature.cs +++ b/src/GeoJSON.Net/Feature/Feature.cs @@ -12,6 +12,88 @@ namespace GeoJSON.Net.Feature { + /// + /// A GeoJSON Feature Object; generic version for strongly typed + /// and + /// + /// + /// See https://tools.ietf.org/html/rfc7946#section-3.2 + /// + public class Feature : GeoJSONObject, IEquatable> + where TGeometry : IGeometryObject + { + [JsonConstructor] + public Feature(TGeometry geometry, TProps properties, string id = null) + { + Geometry = geometry; + Properties = properties; + Id = id; + } + + [JsonProperty(PropertyName = "id", NullValueHandling = NullValueHandling.Ignore)] + public string Id { get; } + + [JsonProperty(PropertyName = "geometry", Required = Required.AllowNull)] + [JsonConverter(typeof(GeometryConverter))] + public TGeometry Geometry { get; } + + [JsonProperty(PropertyName = "properties", Required = Required.AllowNull)] + public TProps Properties { get;} + + /// + /// Equality comparer. + /// + /// + /// In contrast to , this implementation returns true only + /// if and are also equal. See + /// #80 for discussion. The rationale + /// here is that a user explicitly specifying the property type most probably cares about the properties + /// equality. + /// + /// + /// + public bool Equals(Feature other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return base.Equals(other) + && string.Equals(Id, other.Id) + && EqualityComparer.Default.Equals(Geometry, other.Geometry) + && EqualityComparer.Default.Equals(Properties, other.Properties); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((Feature) obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = base.GetHashCode(); + hashCode = (hashCode * 397) ^ (Id != null ? Id.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ EqualityComparer.Default.GetHashCode(Geometry); + hashCode = (hashCode * 397) ^ EqualityComparer.Default.GetHashCode(Properties); + return hashCode; + } + } + + public static bool operator ==(Feature left, Feature right) + { + return object.Equals(left, right); + } + + public static bool operator !=(Feature left, Feature right) + { + return !object.Equals(left, right); + } + } + + /// /// A GeoJSON Feature Object. /// From d0408a3e548ffc13c48375158f59ec4e56d151c7 Mon Sep 17 00:00:00 2001 From: Michael Helmling Date: Sun, 4 Jun 2017 15:59:53 +0100 Subject: [PATCH 2/7] add visual studio settings folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f9d6b392..abc076e5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ lib/* #OSX .DS_Store +/.vs From a279990351ddcdce760934f8c56bbcd1addfbb1c Mon Sep 17 00:00:00 2001 From: Michael Helmling Date: Sat, 17 Jun 2017 21:01:22 +0100 Subject: [PATCH 3/7] Add test for deserializing typed feature --- src/GeoJSON.Net.Tests/Feature/FeatureTests.cs | 25 +++++++++++++++++++ ...s_Can_Deserialize_Typed_Point_Feature.json | 12 +++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Deserialize_Typed_Point_Feature.json diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs b/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs index 8760a217..62a33b3e 100644 --- a/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs +++ b/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs @@ -29,6 +29,31 @@ public void Can_Deserialize_Point_Feature() Assert.AreEqual(feature.Geometry.Type, GeoJSONObjectType.Point); } + private class TypedFeatureProps + { + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("value")] + public double Value { get; set; } + } + + [Test] + public void Can_Deserialize_Typed_Point_Feature() + { + var json = GetExpectedJson(); + var feature = JsonConvert.DeserializeObject>(json); + + Assert.IsNotNull(feature); + + Assert.IsNotNull(feature.Properties); + Assert.AreEqual(feature.Properties.Name, "Dinagat Islands"); + Assert.AreEqual(feature.Properties.Value, 4.2); + + Assert.AreEqual(feature.Id, "test-id"); + + Assert.AreEqual(feature.Geometry.Type, GeoJSONObjectType.Point); + } + [Test] public void Can_Serialize_LineString_Feature() { diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Deserialize_Typed_Point_Feature.json b/src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Deserialize_Typed_Point_Feature.json new file mode 100644 index 00000000..2807e725 --- /dev/null +++ b/src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Deserialize_Typed_Point_Feature.json @@ -0,0 +1,12 @@ +{ + "type": "Feature", + "id": "test-id", + "geometry": { + "type": "Point", + "coordinates": [ 125.6, 10.1 ] + }, + "properties": { + "name": "Dinagat Islands", + "value": 4.2 + } +} \ No newline at end of file From d3a53cd4d6429a4381095bbd96a38f59c94bfb21 Mon Sep 17 00:00:00 2001 From: Michael Helmling Date: Sat, 17 Jun 2017 21:31:58 +0200 Subject: [PATCH 4/7] add tests for generic Feature<,> and fix a bug found with them --- src/GeoJSON.Net.Tests/Feature/FeatureTests.cs | 20 +- ...sts_Can_Serialize_Typed_Point_Feature.json | 12 + .../GeoJSON.Net.Tests.csproj | 276 +++++++++--------- src/GeoJSON.Net/Feature/Feature.cs | 2 + 4 files changed, 174 insertions(+), 136 deletions(-) create mode 100644 src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Serialize_Typed_Point_Feature.json diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs b/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs index 62a33b3e..5aaa9a24 100644 --- a/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs +++ b/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using GeoJSON.Net.Feature; using GeoJSON.Net.Geometry; using Newtonsoft.Json; using NUnit.Framework; @@ -41,7 +42,7 @@ private class TypedFeatureProps public void Can_Deserialize_Typed_Point_Feature() { var json = GetExpectedJson(); - var feature = JsonConvert.DeserializeObject>(json); + var feature = JsonConvert.DeserializeObject>(json); Assert.IsNotNull(feature); @@ -126,6 +127,23 @@ public void Can_Serialize_Point_Feature() JsonAssert.AreEqual(expectedJson, actualJson); } + [Test] + public void Can_Serialize_Typed_Point_Feature() + { + var geometry = new Point(new Position(1, 2)); + var props = new TypedFeatureProps + { + Name = "no name here", + Value = 1.337 + }; + var feature = new Feature(geometry, props, "no id there"); + + var expectedJson = GetExpectedJson(); + var actualJson = JsonConvert.SerializeObject(feature); + + JsonAssert.AreEqual(expectedJson, actualJson); + } + [Test] public void Can_Serialize_Polygon_Feature() { diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Serialize_Typed_Point_Feature.json b/src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Serialize_Typed_Point_Feature.json new file mode 100644 index 00000000..4e68affa --- /dev/null +++ b/src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Serialize_Typed_Point_Feature.json @@ -0,0 +1,12 @@ +{ + "geometry": { + "coordinates": [ 2.0, 1.0 ], + "type": "Point" + }, + "properties": { + "name": "no name here", + "value": 1.337 + }, + "id": "no id there", + "type": "Feature" +} \ No newline at end of file diff --git a/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj b/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj index 544f9421..a0c6858b 100644 --- a/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj +++ b/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj @@ -1,142 +1,148 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {6C93B314-9208-4684-B873-172F7EC81689} - Library - Properties - GeoJSON.Net.Tests - GeoJSON.Net.Tests - v4.5 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - - ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - - ..\packages\NUnit.3.7.0\lib\net45\nunit.framework.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - - - - - - - {8af7c40e-e8c7-425f-a8b1-a4b7e74d3ca9} - GeoJSON.Net - - - + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {6C93B314-9208-4684-B873-172F7EC81689} + Library + Properties + GeoJSON.Net.Tests + GeoJSON.Net.Tests + v4.5 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll + + + ..\packages\NUnit.3.7.0\lib\net45\nunit.framework.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + + + + + + + {8af7c40e-e8c7-425f-a8b1-a4b7e74d3ca9} + GeoJSON.Net + + + + --> \ No newline at end of file diff --git a/src/GeoJSON.Net/Feature/Feature.cs b/src/GeoJSON.Net/Feature/Feature.cs index 37828a69..caa119d4 100644 --- a/src/GeoJSON.Net/Feature/Feature.cs +++ b/src/GeoJSON.Net/Feature/Feature.cs @@ -28,6 +28,8 @@ public Feature(TGeometry geometry, TProps properties, string id = null) Geometry = geometry; Properties = properties; Id = id; + + Type = GeoJSONObjectType.Feature; } [JsonProperty(PropertyName = "id", NullValueHandling = NullValueHandling.Ignore)] From f7e9267e4698945a6c8714ebf6ebd5bd0e9cf307 Mon Sep 17 00:00:00 2001 From: Michael Helmling Date: Sat, 17 Jun 2017 21:35:03 +0200 Subject: [PATCH 5/7] move generic Feature tests to dedicated source file --- src/GeoJSON.Net.Tests/Feature/FeatureTests.cs | 42 -------------- .../Feature/GenericFeatureTests.cs | 55 +++++++++++++++++++ ..._Can_Deserialize_Typed_Point_Feature.json} | 0 ...ts_Can_Serialize_Typed_Point_Feature.json} | 0 .../GeoJSON.Net.Tests.csproj | 5 +- 5 files changed, 58 insertions(+), 44 deletions(-) create mode 100644 src/GeoJSON.Net.Tests/Feature/GenericFeatureTests.cs rename src/GeoJSON.Net.Tests/Feature/{FeatureTests_Can_Deserialize_Typed_Point_Feature.json => GenericFeatureTests_Can_Deserialize_Typed_Point_Feature.json} (100%) rename src/GeoJSON.Net.Tests/Feature/{FeatureTests_Can_Serialize_Typed_Point_Feature.json => GenericFeatureTests_Can_Serialize_Typed_Point_Feature.json} (100%) diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs b/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs index 5aaa9a24..c67fc834 100644 --- a/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs +++ b/src/GeoJSON.Net.Tests/Feature/FeatureTests.cs @@ -30,31 +30,6 @@ public void Can_Deserialize_Point_Feature() Assert.AreEqual(feature.Geometry.Type, GeoJSONObjectType.Point); } - private class TypedFeatureProps - { - [JsonProperty("name")] - public string Name { get; set; } - [JsonProperty("value")] - public double Value { get; set; } - } - - [Test] - public void Can_Deserialize_Typed_Point_Feature() - { - var json = GetExpectedJson(); - var feature = JsonConvert.DeserializeObject>(json); - - Assert.IsNotNull(feature); - - Assert.IsNotNull(feature.Properties); - Assert.AreEqual(feature.Properties.Name, "Dinagat Islands"); - Assert.AreEqual(feature.Properties.Value, 4.2); - - Assert.AreEqual(feature.Id, "test-id"); - - Assert.AreEqual(feature.Geometry.Type, GeoJSONObjectType.Point); - } - [Test] public void Can_Serialize_LineString_Feature() { @@ -127,23 +102,6 @@ public void Can_Serialize_Point_Feature() JsonAssert.AreEqual(expectedJson, actualJson); } - [Test] - public void Can_Serialize_Typed_Point_Feature() - { - var geometry = new Point(new Position(1, 2)); - var props = new TypedFeatureProps - { - Name = "no name here", - Value = 1.337 - }; - var feature = new Feature(geometry, props, "no id there"); - - var expectedJson = GetExpectedJson(); - var actualJson = JsonConvert.SerializeObject(feature); - - JsonAssert.AreEqual(expectedJson, actualJson); - } - [Test] public void Can_Serialize_Polygon_Feature() { diff --git a/src/GeoJSON.Net.Tests/Feature/GenericFeatureTests.cs b/src/GeoJSON.Net.Tests/Feature/GenericFeatureTests.cs new file mode 100644 index 00000000..07766e2c --- /dev/null +++ b/src/GeoJSON.Net.Tests/Feature/GenericFeatureTests.cs @@ -0,0 +1,55 @@ +using GeoJSON.Net.Feature; +using GeoJSON.Net.Geometry; +using Newtonsoft.Json; +using NUnit.Framework; + +namespace GeoJSON.Net.Tests.Feature +{ + + [TestFixture] + public class GenericFeatureTests : TestBase + { + private class TypedFeatureProps + { + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("value")] + public double Value { get; set; } + } + + [Test] + public void Can_Deserialize_Typed_Point_Feature() + { + var json = GetExpectedJson(); + var feature = JsonConvert.DeserializeObject>(json); + + Assert.IsNotNull(feature); + + Assert.IsNotNull(feature.Properties); + Assert.AreEqual(feature.Properties.Name, "Dinagat Islands"); + Assert.AreEqual(feature.Properties.Value, 4.2); + + Assert.AreEqual(feature.Id, "test-id"); + + Assert.AreEqual(feature.Geometry.Type, GeoJSONObjectType.Point); + } + + + [Test] + public void Can_Serialize_Typed_Point_Feature() + { + var geometry = new Point(new Position(1, 2)); + var props = new TypedFeatureProps + { + Name = "no name here", + Value = 1.337 + }; + var feature = new Feature(geometry, props, "no id there"); + + var expectedJson = GetExpectedJson(); + var actualJson = JsonConvert.SerializeObject(feature); + + JsonAssert.AreEqual(expectedJson, actualJson); + } + } +} \ No newline at end of file diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Deserialize_Typed_Point_Feature.json b/src/GeoJSON.Net.Tests/Feature/GenericFeatureTests_Can_Deserialize_Typed_Point_Feature.json similarity index 100% rename from src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Deserialize_Typed_Point_Feature.json rename to src/GeoJSON.Net.Tests/Feature/GenericFeatureTests_Can_Deserialize_Typed_Point_Feature.json diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Serialize_Typed_Point_Feature.json b/src/GeoJSON.Net.Tests/Feature/GenericFeatureTests_Can_Serialize_Typed_Point_Feature.json similarity index 100% rename from src/GeoJSON.Net.Tests/Feature/FeatureTests_Can_Serialize_Typed_Point_Feature.json rename to src/GeoJSON.Net.Tests/Feature/GenericFeatureTests_Can_Serialize_Typed_Point_Feature.json diff --git a/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj b/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj index a0c6858b..ff91919a 100644 --- a/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj +++ b/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj @@ -51,6 +51,7 @@ + @@ -72,7 +73,7 @@ Always - + Always @@ -87,7 +88,7 @@ Always - + Always From 1b9b19b75a5f255ae91665ab6c3b2a4a269a5387 Mon Sep 17 00:00:00 2001 From: Michael Helmling Date: Sat, 17 Jun 2017 21:37:01 +0200 Subject: [PATCH 6/7] add Nunit3TestAdapter package to GeoJSON.Net.Tests Allows to run unit tests in visual studio without installing the VSIX extension. This appears to be the recommended way of running tests within VS now. Also, in VS2017 it was the only way I managed to run the test (and only using the 3.8.0 alpha version of the package). --- src/GeoJSON.Net.Tests/packages.config | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/GeoJSON.Net.Tests/packages.config b/src/GeoJSON.Net.Tests/packages.config index 1478e5af..13e3ab72 100644 --- a/src/GeoJSON.Net.Tests/packages.config +++ b/src/GeoJSON.Net.Tests/packages.config @@ -1,5 +1,6 @@ - - - - + + + + + \ No newline at end of file From be55b83e1af9ad50132a063dcea2ce6880c31ccc Mon Sep 17 00:00:00 2001 From: Michael Helmling Date: Mon, 24 Jul 2017 17:06:01 +0200 Subject: [PATCH 7/7] update NUnit packages (stable version now supports VS 2017 and .NET core) --- src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj b/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj index 3f62ce73..18ed9f41 100644 --- a/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj +++ b/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj @@ -9,8 +9,8 @@ - - + +