Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2498 | - | 1 | |
2 | namespace GMap.NET.Projections |
||
3 | { |
||
4 | using System; |
||
5 | |||
6 | /// <summary> |
||
7 | /// The Mercator projection |
||
8 | /// PROJCS["World_Mercator",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator"],PARAMETER["False_Easting",0],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",0],PARAMETER["standard_parallel_1",0],UNIT["Meter",1]] |
||
9 | /// </summary> |
||
10 | public class MercatorProjection : PureProjection |
||
11 | { |
||
12 | public static readonly MercatorProjection Instance = new MercatorProjection(); |
||
13 | |||
14 | static readonly double MinLatitude = -85.05112878; |
||
15 | static readonly double MaxLatitude = 85.05112878; |
||
16 | static readonly double MinLongitude = -180; |
||
17 | static readonly double MaxLongitude = 180; |
||
18 | |||
19 | public override RectLatLng Bounds |
||
20 | { |
||
21 | get |
||
22 | { |
||
23 | return RectLatLng.FromLTRB(MinLongitude, MaxLatitude, MaxLongitude, MinLatitude); |
||
24 | } |
||
25 | } |
||
26 | |||
27 | readonly GSize tileSize = new GSize(256, 256); |
||
28 | public override GSize TileSize |
||
29 | { |
||
30 | get |
||
31 | { |
||
32 | return tileSize; |
||
33 | } |
||
34 | } |
||
35 | |||
36 | public override double Axis |
||
37 | { |
||
38 | get |
||
39 | { |
||
40 | return 6378137; |
||
41 | } |
||
42 | } |
||
43 | |||
44 | public override double Flattening |
||
45 | { |
||
46 | get |
||
47 | { |
||
48 | return (1.0 / 298.257223563); |
||
49 | } |
||
50 | } |
||
51 | |||
52 | public override GPoint FromLatLngToPixel(double lat, double lng, int zoom) |
||
53 | { |
||
54 | GPoint ret = GPoint.Empty; |
||
55 | |||
56 | lat = Clip(lat, MinLatitude, MaxLatitude); |
||
57 | lng = Clip(lng, MinLongitude, MaxLongitude); |
||
58 | |||
59 | double x = (lng + 180) / 360; |
||
60 | double sinLatitude = Math.Sin(lat * Math.PI / 180); |
||
61 | double y = 0.5 - Math.Log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI); |
||
62 | |||
63 | GSize s = GetTileMatrixSizePixel(zoom); |
||
64 | long mapSizeX = s.Width; |
||
65 | long mapSizeY = s.Height; |
||
66 | |||
67 | ret.X = (long)Clip(x * mapSizeX + 0.5, 0, mapSizeX - 1); |
||
68 | ret.Y = (long)Clip(y * mapSizeY + 0.5, 0, mapSizeY - 1); |
||
69 | |||
70 | return ret; |
||
71 | } |
||
72 | |||
73 | public override PointLatLng FromPixelToLatLng(long x, long y, int zoom) |
||
74 | { |
||
75 | PointLatLng ret = PointLatLng.Empty; |
||
76 | |||
77 | GSize s = GetTileMatrixSizePixel(zoom); |
||
78 | double mapSizeX = s.Width; |
||
79 | double mapSizeY = s.Height; |
||
80 | |||
81 | double xx = (Clip(x, 0, mapSizeX - 1) / mapSizeX) - 0.5; |
||
82 | double yy = 0.5 - (Clip(y, 0, mapSizeY - 1) / mapSizeY); |
||
83 | |||
84 | ret.Lat = 90 - 360 * Math.Atan(Math.Exp(-yy * 2 * Math.PI)) / Math.PI; |
||
85 | ret.Lng = 360 * xx; |
||
86 | |||
87 | return ret; |
||
88 | } |
||
89 | |||
90 | public override GSize GetTileMatrixMinXY(int zoom) |
||
91 | { |
||
92 | return new GSize(0, 0); |
||
93 | } |
||
94 | |||
95 | public override GSize GetTileMatrixMaxXY(int zoom) |
||
96 | { |
||
97 | long xy = (1 << zoom); |
||
98 | return new GSize(xy - 1, xy - 1); |
||
99 | } |
||
100 | } |
||
101 | } |