namespace OsmXmlToRegionConverter; public class Coordinates { public const float RegionSize = 0.01f; public float latitude { get; } public float longitude { get; } public Coordinates(float latitude, float longitude) { this.latitude = latitude; this.longitude = longitude; } public override bool Equals(object? obj) { if (obj == null || obj.GetType() != this.GetType()) return false; Coordinates convObj = (Coordinates)obj; // ReSharper disable twice CompareOfFloatsByEqualityOperator static values return convObj.latitude == this.latitude && convObj.longitude == this.longitude; } public new ulong GetHashCode() { return GetHashCode(latitude, longitude); } public static ulong GetRegionHashCode(float latitude, float longitude) { float latRegion = latitude - latitude % RegionSize; float lonRegion = longitude - longitude % RegionSize; return GetHashCode(latRegion, lonRegion); } public static ulong GetRegionHashCode(Coordinates coordinates) { float latRegion = coordinates.latitude - coordinates.latitude % RegionSize; float lonRegion = coordinates.longitude - coordinates.longitude % RegionSize; return GetHashCode(latRegion, lonRegion); } private const float decimalCoordsSave = 10000; private const ulong offset = 10000000; //Latitude maxChars = 7 //Longitude maxChars = 8 public static ulong GetHashCode(float latitude, float longitude) { ulong latHash = Convert.ToUInt64((latitude + 90) * decimalCoordsSave); ulong lonHash = Convert.ToUInt64((longitude + 180) * decimalCoordsSave); return latHash * offset + lonHash; } public override string ToString() { return string.Format("COORDINATES Lat: {0} Lon: {1}", this.latitude, this.longitude); } public const int ByteSize = sizeof(float) * 2; public static Coordinates FromBytes(byte[] bytes) { using (MemoryStream m = new MemoryStream(bytes)) { using (BinaryReader r = new BinaryReader(m)) { float latitude = r.ReadSingle(); float longitude = r.ReadSingle(); return new Coordinates(latitude, longitude); } } } }