z=1的效果就是将它切分为4份见下图：

NUM:x或者y方向上的图片数

N:第几层z轴

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows;
6
8 {
9     class Mercator
10     {
11         private double NormalToMercator(double y)
12         {
13             y -= 0.5;
14             y *= 2.0 * Math.PI;
15             y = Math.Exp(y * 2.0);
16             y = (y - 1) / (y + 1.0);
17             y = Math.Asin(y);
18             y = y * -180.0 / Math.PI;
19             return y;
20         }
21         private double MercatorToNormal(double y)
22         {
23             y = -y * Math.PI / 180.0;
24             y = Math.Sin(y);
25             y = (1.0 + y) / (1.0 - y);
26             y = 0.5 * Math.Log(y);
27             y *= 1.0 / (2.0 * Math.PI);
28             y += 0.5;
29             return y;
30         }
31         private double getNormailByY(double y,int picnum)
32         {
33             return y/picnum;
34         }
35         private double getYByNormail(double y, int picnum)
36         {
37             return picnum * y;
38         }
39         ///////////////////////////////////////////////
40         ///传入:-26.851029008675013 返回：-26° 51' 3"
41         public string GetSexagesimalNotation(double x)
42         {
43             //to string format: 23° 27′ 30"
44             var ret = "";
45             if (x < 0)
46             {
47                 ret += '-';
48                 x = -x;
49             }
50             ret += Math.Floor(x);
51             ret += "° ";
52
53             x = (x - Math.Floor(x)) * 60;
54             ret += Math.Floor(x);
55             ret += "' ";
56
57             x = (x - Math.Floor(x)) * 60;
58             ret += Math.Floor(x);
59             ret += "\" ";
60
61             return ret;
62         }
63         public Point Google_XYZ_to_LatLng(int x, int y, int z)     //lat [0]  , lng [1]
64         {
65             Point LatLng = new Point();
66             int picnum = 2 << (z - 1);   //z层在x、y轴上存在多少张
67             double onex = 360.0 / picnum;    //平均每一张占用多少经纬度
68             double xlat = onex * x;
69             if (xlat > 360.0)       //如果超过360就剪掉它
70                 xlat = xlat % 360.0;
71             if (xlat > 180.0)
72                 LatLng.X = onex * x - 180.0;
73             else
74                 LatLng.X = -(180.0 - onex * x);
75             LatLng.Y = NormalToMercator(getNormailByY(y, picnum));
76             return LatLng;
77         }
78         public Point Google_LatLngZ_to_XY(double Lat, double Lng, int z)       //return x,y array
79         {
80             Point xy = new Point();
81             int picnum = 2 << (z - 1);   //z层在x、y轴上存在多少张82             double onex = 360.0 / picnum; ////平均每一张占用多少经纬度 83             Lat += 180.0; 84             xy.X = Convert.ToInt32(Lat / onex); //x 85             xy.Y = Convert.ToInt32(getYByNormail(MercatorToNormal(Lng), picnum)); //y 86             return xy; 87         } 88     } 89 }

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml">
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6 <script type="text/javascript" src="jquery-1.8.0.min.js"></script>
7 <script type="text/javascript">
8     $(document).ready(function() 9 { 10 readImage(); 11 }); 12 function readImage() 13 { 14 var url=""; 15 //http://khmdbs0.google.com/pm?v=9&src=app&x=0&y=4&z=4&s=Gali 16 //http://khm1.google.com/kh/v=125&src=app&x= 17 // 18 19 20 if($("#mapTypeSelect").val() == 1)
21         {
22             var xx = parseInt($("#x").val()); 23 var yy = parseInt($("#y").val());
24             var zz = parseInt($("#z").val()); 25 var picnum = 2<<(zz-1); 26 var onex = 360 / picnum; 27 /*var oney = 180 / picnum; 28 if(oney * yy > 90) 29 var lng = -(oney * yy - 90); 30 else 31 var lng = 90 - oney * yy;*/ 32 var lng = NormalToMercator (getNormailByY(yy,picnum)); 33 if(onex * xx > 180) 34 var lat = onex * xx - 180; 35 else 36 var lat = -(180 - onex * xx); 37$("#latlng").text(lng + " , " + lat);
38             $("table td").each(function(i){ 39 var ix = i%5 + parseInt($("#x").val());
40                 var iy = parseInt(i/5) + parseInt($("#y").val()); 41 url = "http://khm1.google.com/kh/v=125&src=app&x="+ix 42 +"&y="+iy+"&z="+$("#z").val();
43                 $(this).html("<img style='width:100%;height:100%;' src='"+url+"'/>"); 44 }); 45 } 46 else if($("#mapTypeSelect").val() == 2)        //soso
47         {
48             var xx = parseInt($("#x").val()); 49 var yy = parseInt($("#y").val());
50             var zz = parseInt($("#z").val()); 51$("table td").each(function(i){
52                 var ix = i%5 + parseInt($("#x").val()); 53 var iy = 2 - parseInt(i/5) + parseInt($("#y").val());
54                 var dx = Math.floor(ix/16);
55                 var dy = Math.floor(iy/16);
56                 url = "http://p1.map.soso.com/sateTiles/"+$("#z").val() 57 +"/"+dx+"/"+dy+"/"+ix+"_"+iy+".jpg"; 58$(this).html("<img style='width:100%;height:100%;' src='"+url+"'/>");
59              });
60         }
61         else if($("#mapTypeSelect").val() == 3) //baidu 62 { 63 var xx = parseInt($("#x").val());
64             var yy = parseInt($("#y").val()); 65 var zz = parseInt($("#z").val());
66             $("table td").each(function(i){ 67 var ix = i%5 + parseInt($("#x").val());
68                 var iy = 2 - parseInt(i/5) + parseInt($("#y").val()); 69 url = "http://q1.baidu.com/it/u=x="+ix+";y="+iy+";z="+$("#z").val()
70                     +";v=009;type=sate&fm=46";
71                 $(this).html("<img style='width:100%;height:100%;' src='"+url+"'/>"); 72 }); 73 } 74 else if($("#mapTypeSelect").val() == 4)        //cangbao
75         {
76             var xx = parseInt($("#x").val()); 77 var yy = parseInt($("#y").val());
78             var zz = parseInt($("#z").val()); 79 var picnum = 2<<(zz-1); 80 var onex = 360 / picnum; 81 /*var oney = 180 / picnum; 82 if(oney * yy > 90) 83 var lng = -(oney * yy - 90); 84 else 85 var lng = 90 - oney * yy;*/ 86 var lng = NormalToMercator (getNormailByY(yy,picnum)); 87 if(onex * xx > 180) 88 var lat = onex * xx - 180; 89 else 90 var lat = -(180 - onex * xx); 91$("#latlng").text(lng + " , " + lat);
92             $("table td").each(function(i){ 93 var ix = i%5 + parseInt($("#x").val());
94                 var iy = parseInt(i/5) + parseInt($("#y").val()); 95 url = "http://khmdbs0.google.com/pm?v=9&src=app&x="+ix 96 +"&y="+iy+"&z="+$("#z").val();
97                 $(this).html("<img style='width:100%;height:100%;' src='"+url+"'/>"); 98 }); 99 } 100 } 101 function left() 102 { 103 var xx = parseInt($("#x").val());
104         $("#x").val(--xx); 105 } 106 function up() 107 { 108 var yy = parseInt($("#y").val());
109         if($("#mapTypeSelect").val() == 2 ||$("#mapTypeSelect").val() == 3 )
110             $("#y").val(++yy); 111 else 112$("#y").val(--yy);
113     }
114     function right()
115     {
116         var xx = parseInt($("#x").val()); 117$("#x").val(++xx);
118     }
119     function down()
120     {
121         var yy = parseInt($("#y").val()); 122 if($("#mapTypeSelect").val() == 2 || $("#mapTypeSelect").val() == 3 ) 123$("#y").val(--yy);
124         else
125             $("#y").val(++yy); 126 } 127 function enter() 128 { 129 var xx = parseInt($("#x").val());
130         var yy = parseInt($("#y").val()); 131 var zz = parseInt($("#z").val());
132         if($("#mapTypeSelect").val() == 1) 133 { 134 var centerX = (xx+2)*2 - 2; 135 var centerY = (yy+1)*2 - 1; 136 var centerZ = zz+1; 137 } 138 else if($("#mapTypeSelect").val() == 2 || $("#mapTypeSelect").val() == 3 ) 139 { 140 var centerX = (xx+2)*2 - 2; 141 var centerY = (yy-1)*2 + 3; 142 var centerZ = zz+1; 143 } 144$("#x").val(centerX);
145         $("#y").val(centerY); 146$("#z").val(centerZ);
147     }
148     function exit()
149     {
150         var xx = parseInt($("#x").val()); 151 var yy = parseInt($("#y").val());
152         var zz = parseInt($("#z").val()); 153 if($("#mapTypeSelect").val() == 1)
154         {
155             var centerX = parseInt((xx+2)/2) - 2;
156             var centerY = parseInt((yy+1)/2) - 1;
157             var centerZ = zz-1;
158         }
159         else if($("#mapTypeSelect").val() == 2 ||$("#mapTypeSelect").val() == 3 )
160         {
161             var centerX = parseInt((xx+2)/2) - 2;
162             var centerY = parseInt((yy-1)/2);
163             var centerZ = zz-1;
164         }
165         $("#x").val(centerX); 166$("#y").val(centerY);
167         $("#z").val(centerZ); 168 } 169$(this).bind('focus',function(event){
170         $(this).select(); 171 }); 172$(document).bind('keydown',function(e){
173       e = (e) ? e : ((window.event) ? window.event : "");
174       var key = e.keyCode?e.keyCode:e.which;
175             switch(key) {
176             case 37:
177                 //left
178                 left();
180                 break;
181             case 38:
182                 //up
183                 up();
185                 break;
186             case 39:
187                 //right
188                 right();
190                 break;
191             case 40:
192                 //down
193                 down();
195                 break;
196             /*case 13:
197                 //enter
198                 enter();
200                 break;*/
201             case 69:
202                 //E
203                 enter();
205                 break;
206             /*case 27:
207                 //exit
208                 exit();
210                 break;*/
211             case 81:
212                 //Q
213                 exit();
215                 break;
216             default:
218                 break;
219             }
220         });
221         function MercatorToNormal(y)
222         {
223             y = -y * Math.PI / 180;    // convert to radians
224             y = Math.sin(y);
225             y = (1+y)/(1-y);
226             y = 0.5 * Math.log(y);
227             y *= 1.0 / (2 * Math.PI);    // scale factor from radians to normalized
228             y += 0.5;    // and make y range from 0 - 1
229             return y;
230         }
231
232         function NormalToMercator(y)
233         {
234             y -= 0.5;
235             y *= 2 * Math.PI;
236             y = Math.exp(y * 2);
237             y = (y-1)/(y+1);
238             y = Math.asin(y);
239             y = y * -180/Math.PI;
240             return y;
241         }
242         function getNormailByY(y,picnum)
243         {
244             /*var scale = 1.0;
245             var ry = 0.0;
246             for (var i = 0; i< y ; i++)
247             {
248                 scale *= 0.5;
249                 ry += scale;
250             }
251             return ry;*/
252             return y/picnum;
253         }
254         function changeMapTypeSelect()
255         {
256             if($("#mapTypeSelect").val() == 2) 257 { 258$("#x").val(10);
259                 $("#y").val(8); 260$("#z").val(4);
261             }
262             else if($("#mapTypeSelect").val() == 1) 263 { 264$("#x").val(10);
265                 $("#y").val(5); 266$("#z").val(4);
267             }
268             else if ($("#mapTypeSelect").val() == 3 ) 269 { 270$("#x").val(3);
271                 $("#y").val(0); 272$("#z").val(5);
273             }
275         }
276
277 </script>
279 <body>
280 <form action="#">
281 x:<input id="x" type="text" value="10" style="width:60px;"/>
282 y:<input id="y" type="text" value="5" style="width:60px;"/>
283 z:<input id="z" type="text" value="4" style="width:60px;"/>
284 <input type="submit" value="重新載入" onclick="readImage()"/>&nbsp;&nbsp;&nbsp;<span style="font-size:12px; color:#808080">
285 <select id="mapTypeSelect" onchange="changeMapTypeSelect()">
287   <option value="2">SosoMap</option>
288   <option value="3">BaiduMap</option>
289   <option value="4">藏宝图</option>
290 </select>
291 使用鍵盤熱鍵上下左右鍵調節方向，E、Q控制地圖縮放</span>
298 </form>
299 左上角經緯度:&nbsp;&nbsp;<span id="latlng"></span>
301   <tr>
302     <td></td>
303     <td></td>
304     <td></td>
305     <td></td>
306     <td></td>
307   </tr>
308   <tr>
309     <td></td>
310     <td></td>
311     <td></td>
312     <td></td>
313     <td></td>
314   </tr>
315   <tr>
316     <td></td>
317     <td></td>
318     <td></td>
319     <td></td>
320     <td></td>
321   </tr>
322 </table>
323 </body>
324 </html>