namespace GMap.NET.Projections { using System; class MercatorProjectionYandex : PureProjection { public static readonly MercatorProjectionYandex Instance = new MercatorProjectionYandex(); static readonly double MinLatitude = -85.05112878; static readonly double MaxLatitude = 85.05112878; static readonly double MinLongitude = -177; static readonly double MaxLongitude = 177; static readonly double RAD_DEG = 180 / Math.PI; static readonly double DEG_RAD = Math.PI / 180; static readonly double MathPiDiv4 = Math.PI / 4; public override RectLatLng Bounds { get { return RectLatLng.FromLTRB(MinLongitude, MaxLatitude, MaxLongitude, MinLatitude); } } GSize tileSize = new GSize(256, 256); public override GSize TileSize { get { return tileSize; } } public override double Axis { get { return 6356752.3142; } } public override double Flattening { get { return (1.0 / 298.257223563); } } public override GPoint FromLatLngToPixel(double lat, double lng, int zoom) { lat = Clip(lat, MinLatitude, MaxLatitude); lng = Clip(lng, MinLongitude, MaxLongitude); double rLon = lng * DEG_RAD; // Math.PI / 180; double rLat = lat * DEG_RAD; // Math.PI / 180; double a = 6378137; double k = 0.0818191908426; double z = Math.Tan(MathPiDiv4 + rLat / 2) / Math.Pow((Math.Tan(MathPiDiv4 + Math.Asin(k * Math.Sin(rLat)) / 2)), k); double z1 = Math.Pow(2, 23 - zoom); double DX = ((20037508.342789 + a * rLon) * 53.5865938 / z1); double DY = ((20037508.342789 - a * Math.Log(z)) * 53.5865938 / z1); GPoint ret = GPoint.Empty; ret.X = (long)DX; ret.Y = (long)DY; return ret; } public override PointLatLng FromPixelToLatLng(long x, long y, int zoom) { GSize s = GetTileMatrixSizePixel(zoom); double mapSizeX = s.Width; double mapSizeY = s.Height; double a = 6378137; double c1 = 0.00335655146887969; double c2 = 0.00000657187271079536; double c3 = 0.00000001764564338702; double c4 = 0.00000000005328478445; double z1 = (23 - zoom); double mercX = (x * Math.Pow(2, z1)) / 53.5865938 - 20037508.342789; double mercY = 20037508.342789 - (y * Math.Pow(2, z1)) / 53.5865938; double g = Math.PI / 2 - 2 * Math.Atan(1 / Math.Exp(mercY / a)); double z = g + c1 * Math.Sin(2 * g) + c2 * Math.Sin(4 * g) + c3 * Math.Sin(6 * g) + c4 * Math.Sin(8 * g); PointLatLng ret = PointLatLng.Empty; ret.Lat = z * RAD_DEG; ret.Lng = mercX / a * RAD_DEG; return ret; } public override GSize GetTileMatrixMinXY(int zoom) { return new GSize(0, 0); } public override GSize GetTileMatrixMaxXY(int zoom) { long xy = (1 << zoom); return new GSize(xy - 1, xy - 1); } } }