// Copyright © Joerg Battermann 2014, Matt Hunt 2017 using System.Linq; using System.Runtime.Serialization; using GeoJSON.Net.Converters; using GeoJSON.Net.CoordinateReferenceSystem; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using System.Collections.Generic; using System; namespace GeoJSON.Net { /// /// Base class for all IGeometryObject implementing types /// [JsonObject(MemberSerialization.OptIn)] public abstract class GeoJSONObject : IGeoJSONObject, IEqualityComparer, IEquatable { internal static readonly DoubleTenDecimalPlaceComparer DoubleComparer = new DoubleTenDecimalPlaceComparer(); /// /// Gets or sets the (optional) /// Bounding Boxes. /// /// /// The value of must be a 2*n array where n is the number of dimensions represented in /// the /// contained geometries, with the lowest values for all axes followed by the highest values. /// The axes order of a bbox follows the axes order of geometries. /// In addition, the coordinate reference system for the bbox is assumed to match the coordinate reference /// system of the GeoJSON object of which it is a member. /// [JsonProperty(PropertyName = "bbox", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)] public double[] BoundingBoxes { get; set; } /// /// Gets or sets the (optional) /// /// Coordinate Reference System /// Object. /// /// /// /// The Coordinate Reference System Objects. /// [JsonProperty(PropertyName = "crs", Required = Required.Default, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, NullValueHandling = NullValueHandling.Include)] [JsonConverter(typeof(CrsConverter))] //[DefaultValue(typeof(DefaultCRS), "")] public ICRSObject CRS { get; set; } /// /// The (mandatory) type of the /// GeoJSON Object. /// [JsonProperty(PropertyName = "type", Required = Required.Always, DefaultValueHandling = DefaultValueHandling.Include)] [JsonConverter(typeof(StringEnumConverter))] public abstract GeoJSONObjectType Type { get; } #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 GeoJSONObject); } /// /// Determines whether the specified object is equal to the current object /// public bool Equals(GeoJSONObject other) { return Equals(this, other); } /// /// Determines whether the specified object instances are considered equal /// public bool Equals(GeoJSONObject left, GeoJSONObject right) { if (ReferenceEquals(left, right)) { return true; } if (ReferenceEquals(null, right)) { return false; } if (left.Type != right.Type) { return false; } if (!Equals(left.CRS, right.CRS)) { return false; } var leftIsNull = ReferenceEquals(null, left.BoundingBoxes); var rightIsNull = ReferenceEquals(null, right.BoundingBoxes); var bothAreMissing = leftIsNull && rightIsNull; if (bothAreMissing || leftIsNull != rightIsNull) { return bothAreMissing; } return left.BoundingBoxes.SequenceEqual(right.BoundingBoxes, DoubleComparer); } /// /// Determines whether the specified object instances are considered equal /// public static bool operator ==(GeoJSONObject left, GeoJSONObject right) { if (ReferenceEquals(left, right)) { return true; } if (ReferenceEquals(null, right)) { return false; } return left.Equals(right); } /// /// Determines whether the specified object instances are not considered equal /// public static bool operator !=(GeoJSONObject left, GeoJSONObject right) { return !(left == right); } /// /// Returns the hash code for this instance /// public override int GetHashCode() { return ((int)Type).GetHashCode(); } /// /// Returns the hash code for the specified object /// public int GetHashCode(GeoJSONObject obj) { return obj.GetHashCode(); } #endregion } }