//----------------------------------------------------------------------- // // Copyright (c) 2016 Mapbox. All rights reserved. // //----------------------------------------------------------------------- namespace Mapbox.Map { using System; using Mapbox.Utils; /// /// Data type to store Web Mercator tile scheme. /// See tile IDs in action. /// public struct CanonicalTileId : IEquatable { /// The zoom level. public readonly int Z; /// The X coordinate in the tile grid. public readonly int X; /// The Y coordinate in the tile grid. public readonly int Y; /// /// Initializes a new instance of the struct, /// representing a tile coordinate in a slippy map. /// /// The z coordinate or the zoom level. /// The x coordinate. /// The y coordinate. public CanonicalTileId(int z, int x, int y) { this.Z = z; this.X = x; this.Y = y; } internal CanonicalTileId(UnwrappedTileId unwrapped) { var z = unwrapped.Z; var x = unwrapped.X; var y = unwrapped.Y; var wrap = (x < 0 ? x - (1 << z) + 1 : x) / (1 << z); this.Z = z; this.X = x - wrap * (1 << z); this.Y = y < 0 ? 0 : Math.Min(y, (1 << z) - 1); } /// /// Get the cordinate at the top left of corner of the tile. /// /// The coordinate. public Vector2d ToVector2d() { double n = Math.PI - ((2.0 * Math.PI * this.Y) / Math.Pow(2.0, this.Z)); double lat = 180.0 / Math.PI * Math.Atan(Math.Sinh(n)); double lng = (this.X / Math.Pow(2.0, this.Z) * 360.0) - 180.0; // FIXME: Super hack because of rounding issues. return new Vector2d(lat - 0.0001, lng + 0.0001); } /// /// Returns a that represents the current /// . /// /// /// A that represents the current /// . /// public override string ToString() { return this.Z + "/" + this.X + "/" + this.Y; } #region Equality public bool Equals(CanonicalTileId other) { return this.X == other.X && this.Y == other.Y && this.Z == other.Z; } public override int GetHashCode() { return X ^ Y ^ Z; } public static bool operator ==(CanonicalTileId a, CanonicalTileId b) { return a.X == b.X && a.Y == b.Y && a.Z == b.Z; } public static bool operator !=(CanonicalTileId a, CanonicalTileId b) { return !(a == b); } public override bool Equals(object obj) { if (obj is CanonicalTileId) { return this.Equals((CanonicalTileId)obj); } else { return false; } } #endregion } }