From a7a828d27b19b487e9e89d0f81d5ca0cc8c8a234 Mon Sep 17 00:00:00 2001 From: Matt Hunt Date: Fri, 28 Oct 2022 16:05:40 +0100 Subject: [PATCH] Adding typed feature collection --- README.md | 2 +- .../Feature/FeatureCollectionTests.cs | 23 ++++ ...ollectionTests_Can_DeserializeGeneric.json | 76 +++++++++++ .../GeoJSON.Net.Tests.csproj | 3 + src/GeoJSON.Net/Feature/FeatureCollection.cs | 120 ++++++++++++++++++ 5 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 src/GeoJSON.Net.Tests/Feature/FeatureCollectionTests_Can_DeserializeGeneric.json diff --git a/README.md b/README.md index 2bf76685..dc59bf94 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Backers on Open Collective](https://opencollective.com/geojson-net/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/geojson-net/sponsors/badge.svg)](#sponsors) [![NuGet Version](http://img.shields.io/nuget/v/GeoJSON.NET.svg?style=flat)](https://www.nuget.org/packages/GeoJSON.NET/) +[![Backers on Open Collective](https://opencollective.com/geojson-net/tiers/backer/badge.svg?label=backer&color=brightgreen)](#backers) [![Sponsors on Open Collective](https://opencollective.com/geojson-net/sponsors/badge.svg)](#sponsors) [![NuGet Version](http://img.shields.io/nuget/v/GeoJSON.NET.svg?style=flat)](https://www.nuget.org/packages/GeoJSON.NET/) [![Build status](https://dev.azure.com/GeoJSON-Net/GeoJSON.Net/_apis/build/status/GeoJSON.Net)](https://dev.azure.com/GeoJSON-Net/GeoJSON.Net/_build/latest?definitionId=1) # GeoJSON.NET diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureCollectionTests.cs b/src/GeoJSON.Net.Tests/Feature/FeatureCollectionTests.cs index 8ddb9fca..fe8d606b 100644 --- a/src/GeoJSON.Net.Tests/Feature/FeatureCollectionTests.cs +++ b/src/GeoJSON.Net.Tests/Feature/FeatureCollectionTests.cs @@ -27,12 +27,29 @@ public void Can_Deserialize() var featureCollection = JsonConvert.DeserializeObject(json); + 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 Can_DeserializeGeneric() + { + string json = GetExpectedJson(); + + var featureCollection = JsonConvert.DeserializeObject>(json); + + 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); + } + + [Test] public void FeatureCollectionSerialization() @@ -171,4 +188,10 @@ private void Assert_Are_Equal(FeatureCollection left, FeatureCollection right) Assert.AreEqual(left.GetHashCode(), right.GetHashCode()); } } + + + internal class FeatureCollectionTestPropertyObject { + public string Name { get; set; } + public int Size { get; set; } + } } \ No newline at end of file diff --git a/src/GeoJSON.Net.Tests/Feature/FeatureCollectionTests_Can_DeserializeGeneric.json b/src/GeoJSON.Net.Tests/Feature/FeatureCollectionTests_Can_DeserializeGeneric.json new file mode 100644 index 00000000..d130dadc --- /dev/null +++ b/src/GeoJSON.Net.Tests/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.Net.Tests/GeoJSON.Net.Tests.csproj b/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj index 4dc31a12..f3e95507 100644 --- a/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj +++ b/src/GeoJSON.Net.Tests/GeoJSON.Net.Tests.csproj @@ -20,6 +20,9 @@ Always + + Always + diff --git a/src/GeoJSON.Net/Feature/FeatureCollection.cs b/src/GeoJSON.Net/Feature/FeatureCollection.cs index a1db7979..d1f8f8af 100644 --- a/src/GeoJSON.Net/Feature/FeatureCollection.cs +++ b/src/GeoJSON.Net/Feature/FeatureCollection.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Newtonsoft.Json; using System.Linq; +using GeoJSON.Net.Geometry; namespace GeoJSON.Net.Feature { @@ -69,6 +70,7 @@ public bool Equals(FeatureCollection left, FeatureCollection right) { return left.Features.SequenceEqual(right.Features); } + return false; } @@ -81,10 +83,12 @@ public bool Equals(FeatureCollection left, FeatureCollection right) { return true; } + if (ReferenceEquals(null, right)) { return false; } + return left != null && left.Equals(right); } @@ -106,6 +110,7 @@ public override int GetHashCode() { hash = (hash * 397) ^ feature.GetHashCode(); } + return hash; } @@ -119,4 +124,119 @@ public int GetHashCode(FeatureCollection other) #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) + { + throw new ArgumentNullException(nameof(features)); + } + + Features = features; + } + + public override GeoJSONObjectType Type => GeoJSONObjectType.FeatureCollection; + + /// + /// Gets the features. + /// + /// The features. + [JsonProperty(PropertyName = "features", Required = Required.Always)] + 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)) + { + return left.Features.SequenceEqual(right.Features); + } + + return false; + } + + /// + /// Determines whether the specified object instances are considered equal + /// + public static bool operator ==(FeatureCollection left, FeatureCollection right) + { + if (ReferenceEquals(left, right)) + { + return true; + } + + if (ReferenceEquals(null, right)) + { + return false; + } + + 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) + { + hash = (hash * 397) ^ feature.GetHashCode(); + } + + return hash; + } + + /// + /// Returns the hash code for the specified object + /// + public int GetHashCode(FeatureCollection other) + { + return other.GetHashCode(); + } + + #endregion + } } \ No newline at end of file