// Copyright © Joerg Battermann 2014, Matt Hunt 2017 using GeoJSON.Text.Converters; using GeoJSON.Text.CoordinateReferenceSystem; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text.Json.Serialization; namespace GeoJSON.Text { /// /// Base class for all IGeometryObject implementing types /// public abstract class GeoJSONObject : IGeoJSONObject, IEqualityComparer, IEquatable { internal static readonly DoubleTenDecimalPlaceComparer DoubleComparer = new(); /// /// 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. /// [JsonPropertyName("bbox")] [JsonConverter(typeof(BoundingBoxConverter))] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public double[] BoundingBoxes { get; set; } /// /// Gets or sets the (optional) /// /// Coordinate Reference System /// Object. /// /// /// /// The Coordinate Reference System Objects. /// [JsonPropertyName("crs")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] [JsonConverter(typeof(CrsConverter))] public ICRSObject CRS { get; set; } /// /// The (mandatory) type of the /// GeoJSON Object. /// [JsonPropertyName("type")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] 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 (right is null) { return false; } if (left.Type != right.Type) { return false; } if (!Equals(left.CRS, right.CRS)) { return false; } var leftIsNull = left.BoundingBoxes is null; var rightIsNull = right.BoundingBoxes is null; 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 (right is null) { 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 } }