Openlayers加載騰訊、高德、天地圖


之前加載的百度地圖,偏移較大,一直沒有再測試,於是將騰訊、高德、天地圖的整理一下,方便查看。

騰訊js代碼:

 1 OpenLayers.Layer.QQ = OpenLayers.Class(OpenLayers.Layer.TileCache, {
 2     sateTiles: !1,
 3     initialize: function(a, b, c) {
 4         var d = OpenLayers.Util.extend({
 5             format: "image/png",
 6             isBaseLayer: !0
 7         },
 8         c);
 9         OpenLayers.Layer.TileCache.prototype.initialize.apply(this, [a, b, {},
10         d]),
11         this.extension = this.format.split("/")[1].toLowerCase(),
12         this.extension = "jpg" == this.extension ? "jpeg": this.extension,
13         this.transitionEffect = "resize",
14         this.buffer = 0
15     },
16     getURL: function(a) {
17         var b = this.map.getResolution(),
18         c = this.map.getMaxExtent(),
19         d = this.tileSize,
20         e = this.map.zoom,
21         f = Math.round((a.left - c.left) / (b * d.w)),
22         g = Math.round((c.top - a.top) / (b * d.h)),
23         h = new Array(0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 3, 0, 7, 0, 7, 0, 15, 0, 15, 0, 31, 0, 31, 0, 63, 4, 59, 0, 127, 12, 115, 0, 225, 28, 227, 356, 455, 150, 259, 720, 899, 320, 469, 1440, 1799, 650, 929, 2880, 3589, 1200, 2069, 5760, 7179, 2550, 3709, 11520, 14349, 5100, 7999, 23060, 28689, 10710, 15429, 46120, 57369, 20290, 29849, 89990, 124729, 41430, 60689, 184228, 229827, 84169, 128886),
24         i = 4 * e,
25         j = h[i++],
26         k = h[i++],
27         l = h[i++],
28         h = h[i],
29         m = this.sateTiles ? ".jpg": ".png";
30         if (f >= j && k >= f && g >= l && h >= g) {
31             g = Math.pow(2, e) - 1 - g;
32             var n = 'z=' + e + '&x=' + f + '&y=' + g + '&type=vector&style=0&v=1.1.1'
33         }
34         var o = this.url;
35         return OpenLayers.Util.isArray(o) && n && (o = this.selectUrl(n, o)),
36         o + n
37     },
38     clone: function(a) {
39         return null == a && (a = new OpenLayers.Layer.QQ(this.name, this.url, this.options)),
40         a = OpenLayers.Layer.TileCache.prototype.clone.apply(this, [a])
41     },
42     CLASS_NAME: "OpenLayers.Layer.QQ"
43 });
View Code

  QQ地圖的服務地址換了,這里記下以前的地址(屏蔽的代碼)和現在的地址。

 1     //QQ地圖
 2     map.addLayer(
 3         new OpenLayers.Layer.QQ("QQ地圖",
 4             [
 5                 //"http://p0.map.soso.com/maptilesv2/",
 6                 //"http://p1.map.soso.com/maptilesv2/",
 7                 //"http://p2.map.soso.com/maptilesv2/", 
 8                 //"http://p3.map.soso.com/maptilesv2/"
 9                 'http://rt0.map.gtimg.com/realtimerender?',
10                 'http://rt1.map.gtimg.com/realtimerender?',
11                 'http://rt2.map.gtimg.com/realtimerender?',
12                 'http://rt3.map.gtimg.com/realtimerender?'
13             ],
14             {
15                 sateTiles: false
16             }
17         )
18     );
View Code

 

QQ地圖和高德地圖為火星坐標,糾正坐標可以用同一套方法,網上有js文件可以下載。

高德地圖:

 1 OpenLayers.Layer.Gaode = OpenLayers.Class(OpenLayers.Layer.TileCache, {
 2     initialize: function (name, url, options) {
 3         var tempoptions = OpenLayers.Util.extend({
 4             'format': 'image/png',
 5             isBaseLayer: true
 6         }, options);
 7         OpenLayers.Layer.TileCache.prototype.initialize.apply(this, [name, url, {},    tempoptions]);
 8         this.extension = this.format.split('/')[1].toLowerCase();
 9         this.extension = (this.extension == 'jpg') ? 'jpeg' : this.extension;
10         this.transitionEffect = "resize";
11         this.buffer = 0;
12     },
13     getURL: function (bounds) {
14         var retUrl = this.url+"lang=zh_cn&size=1&scale=1&style=8&";
15         var res = this.map.getResolution();
16         var bbox = this.map.getMaxExtent();
17         var size = this.tileSize;
18         //計算列號 
19         var tileX = Math.round((bounds.left - bbox.left) / (res * size.w));
20         //計算行號
21         var tileY = Math.round((bbox.top - bounds.top) / (res * size.h));
22         //當前的等級 
23         debugger;
24         var tileZ = this.map.zoom-1;
25         if (tileX < 0) tileX = tileX + Math.round(bbox.getWidth() / bounds.getWidth());
26         if (tileY < 0) tileY = tileY + Math.round(bbox.getHeight() / bounds.getHeight());
27         //tileY = (Math.pow(2, tileZ) - 1 - tileY);
28         //tileY = Math.pow(2, tileZ)-tileY+Math.pow(2,this.map.zoom-3);
29         tileY = 1+tileY+Math.pow(2,this.map.zoom-3);
30         console.log(tileY+" =tileY");
31         return retUrl+"x="+tileX+"&y="+tileY+"&z="+this.map.zoom;
32     },
33 
34     clone: function (obj) {
35         if (obj == null) {
36         obj = new OpenLayers.Layer.Gaode(this.name, this.url, this.options);
37         }
38         obj = OpenLayers.Layer.TileCache.prototype.clone.apply(this, [obj]);
39         return obj;
40     },
41     CLASS_NAME: "OpenLayers.Layer.Gaode"
42 });
View Code

加載高德地圖的地址,其中屏蔽的地址是下載到本機的離線地圖使用的瓦片地址,其他離線地圖也類似。

 1     //高德地圖
 2     var vecLayer = new OpenLayers.Layer.XYZ("高德地圖", [
 3         "http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x=${x}&y=${y}&z=${z}",
 4         "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x=${x}&y=${y}&z=${z}",
 5         "http://webrd03.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x=${x}&y=${y}&z=${z}",
 6         "http://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x=${x}&y=${y}&z=${z}"
 7         //"data/roadmap/${z}/${x}/${y}.png"
 8     ], {
 9         isBaseLayer: true,
10         visibility: true,
11         displayInLayerSwitcher: true
12     });
13     map.addLayer(vecLayer);
View Code

 

天地圖可以直接使用,WGS84坐標,除了長得丑了點以外,其他都還好。

  1 OpenLayers.Layer.TDT = OpenLayers.Class(OpenLayers.Layer.Grid, {
  2  
  3     mapType: null,
  4     mirrorUrls: null,
  5     topLevel: null,
  6     bottomLevel: null,
  7  
  8     topLevelIndex: 0,
  9     bottomLevelIndex: 20,
 10     topTileFromX: -180,
 11     topTileFromY: 90,
 12     topTileToX: 180,
 13     topTileToY: -270,
 14  
 15     isBaseLayer: true,
 16  
 17     initialize: function (name,options) {
 18  
 19         options.topLevel = options.topLevel ? options.topLevel : this.topLevelIndex;
 20         options.bottomLevel = options.bottomLevel ? options.bottomLevel : this.bottomLevelIndex;
 21         options.maxResolution = this.getResolutionForLevel(options.topLevel);
 22         options.minResolution = this.getResolutionForLevel(options.bottomLevel);
 23  
 24         var newArguments = [name, {}, {}, options];
 25         OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
 26     },
 27  
 28     clone: function (obj) {
 29  
 30         if (obj == null) {
 31             obj = new OpenLayers.Layer.TDTLayer(this.name, this.url, this.options);
 32         }
 33  
 34         obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
 35  
 36         return obj;
 37     },
 38  
 39     getURL: function (bounds) {
 40         var level = this.getLevelForResolution(this.map.getResolution()); 
 41         var coef = 360 / Math.pow(2, level); 
 42         var x_num = this.topTileFromX < this.topTileToX ? Math.round((bounds.left - this.topTileFromX) / coef) : Math.round((this.topTileFromX - bounds.right) / coef);
 43         var y_num = this.topTileFromY < this.topTileToY ? Math.round((bounds.bottom - this.topTileFromY) / coef) : Math.round((this.topTileFromY - bounds.top) / coef);
 44          
 45         switch(level){
 46             case 8:
 47                 url="http://tile6.tianditu.com/DataServer?T=tdt_vip_img_2_10_120627";
 48                 break
 49             case 9:
 50                 url="http://tile5.tianditu.com/DataServer?T=tdt_vip_img_2_10_120627";
 51                 break
 52             case 10:
 53                 url="http://tile5.tianditu.com/DataServer?T=tdt_vip_img_2_10_120627";
 54                 break
 55             case 11:
 56                 url:"http://tile1.tianditu.com/DataServer?T=E11N";
 57                 break
 58             case 12:
 59                 url="http://tile6.tianditu.com/DataServer?T=E12N";
 60                 break
 61             case 13:
 62                 url="http://tile3.tianditu.com/DataServer?T=E13N";
 63                 break
 64             case 14:
 65                 url="http://tile2.tianditu.com/DataServer?T=E14N";
 66                 break
 67             case 15:
 68                 url="http://tile5.tianditu.com/DataServer?T=tdt_vip_img_120627_dyd"
 69                 break
 70             case 16:
 71                 url="http://tile2.tianditu.com/DataServer?T=tdt_vip_img_120627_dyd";
 72                 break
 73             case 17:
 74                 url="http://tile1.tianditu.com/DataServer?T=tdt_vip_img_120627_dyd";
 75                 break
 76             case 18:
 77                 url="http://tile0.tianditu.com/DataServer?T=tdt_vip_img_120627_dyd";
 78                 break
 79         }
 80  
 81         return this.getFullRequestString({ T: null, X: x_num, Y: y_num, L: level }, url);
 82     },
 83     selectUrl: function (a, b) { return b[a % b.length] },
 84     getLevelForResolution: function (res) {
 85         var ratio = this.getMaxResolution() / res;
 86         if (ratio < 1) return 0;
 87         for (var level = 0; ratio / 2 >= 1; )
 88         { level++; ratio /= 2; }
 89         return level;
 90     },
 91     getResolutionForLevel: function (level) {
 92         return 360 / 256 / Math.pow(2, level);
 93     },
 94     getMaxResolution: function () {
 95         return this.getResolutionForLevel(this.topLevelIndex)
 96     },
 97     getMinResolution: function () {
 98         return this.getResolutionForLevel(this.bottomLevelIndex)
 99     },
100     addTile: function (bounds, position) {
101         var url = this.getURL(bounds);
102         return new OpenLayers.Tile.Image(this, position, bounds, url, this.tileSize);
103     },
104  
105     CLASS_NAME: "OpenLayers.Layer.TDT"
106 });
View Code

天地圖底圖和標注,分為兩個圖層來加載顯示的。

 1 //天地圖
 2     map.addLayers([
 3         new OpenLayers.Layer.XYZ(
 4             "天地圖",
 5                  [
 6                  "http://t0.tianditu.com/DataServer?T=vec_w&X=${x}&Y=${y}&L=${z}",
 7                  "http://t1.tianditu.com/DataServer?T=vec_w&X=${x}&Y=${y}&L=${z}",
 8                  "http://t2.tianditu.com/DataServer?T=vec_w&X=${x}&Y=${y}&L=${z}",
 9                  "http://t3.tianditu.com/DataServer?T=vec_w&X=${x}&Y=${y}&L=${z}",
10                  "http://t4.tianditu.com/DataServer?T=vec_w&X=${x}&Y=${y}&L=${z}",
11                  "http://t5.tianditu.com/DataServer?T=vec_w&X=${x}&Y=${y}&L=${z}",
12                  "http://t6.tianditu.com/DataServer?T=vec_w&X=${x}&Y=${y}&L=${z}",
13                  "http://t7.tianditu.com/DataServer?T=vec_w&X=${x}&Y=${y}&L=${z}"
14                  ],
15                  {
16                      projection: new OpenLayers.Projection("EPSG:900913"),
17                      isBaseLayer: true
18                  }
19             ),
20             new OpenLayers.Layer.XYZ(
21                 "天地圖標注",
22                 [
23                  "http://t0.tianditu.com/DataServer?T=cva_w&X=${x}&Y=${y}&L=${z}",
24                  "http://t1.tianditu.com/DataServer?T=cva_w&X=${x}&Y=${y}&L=${z}",
25                  "http://t2.tianditu.com/DataServer?T=cva_w&X=${x}&Y=${y}&L=${z}",
26                  "http://t3.tianditu.com/DataServer?T=cva_w&X=${x}&Y=${y}&L=${z}",
27                  "http://t4.tianditu.com/DataServer?T=cva_w&X=${x}&Y=${y}&L=${z}",
28                  "http://t5.tianditu.com/DataServer?T=cva_w&X=${x}&Y=${y}&L=${z}",
29                  "http://t6.tianditu.com/DataServer?T=cva_w&X=${x}&Y=${y}&L=${z}",
30                  "http://t7.tianditu.com/DataServer?T=cva_w&X=${x}&Y=${y}&L=${z}"
31                 ],
32                 {
33                     projection: new OpenLayers.Projection("EPSG:900913"),
34                                     isBaseLayer: false,
35                                     visibility:false
36 
37                 }
38             )
39         ]
40         );
View Code

 

火星坐標和WGS84坐標相互轉換的js文件,百度搜一下有下載的文件:

  1 var GPS = {
  2     PI: 3.14159265358979324,
  3     x_pi: 3.14159265358979324 * 3000.0 / 180.0,
  4     delta: function (lat, lon) {
  5         // Krasovsky 1940
  6         //
  7         // a = 6378245.0, 1/f = 298.3
  8         // b = a * (1 - f)
  9         // ee = (a^2 - b^2) / a^2;
 10         var a = 6378245.0; //  a: 衛星橢球坐標投影到平面地圖坐標系的投影因子。
 11         var ee = 0.00669342162296594323; //  ee: 橢球的偏心率。
 12         var dLat = this.transformLat(lon - 105.0, lat - 35.0);
 13         var dLon = this.transformLon(lon - 105.0, lat - 35.0);
 14         var radLat = lat / 180.0 * this.PI;
 15         var magic = Math.sin(radLat);
 16         magic = 1 - ee * magic * magic;
 17         var sqrtMagic = Math.sqrt(magic);
 18         dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * this.PI);
 19         dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);
 20         return { 'lat': dLat, 'lon': dLon };
 21     },
 22 
 23     //WGS-84 to GCJ-02
 24     gcj_encrypt: function (wgsLat, wgsLon) {
 25         if (this.outOfChina(wgsLat, wgsLon))
 26             return { 'lat': wgsLat, 'lon': wgsLon };
 27 
 28         var d = this.delta(wgsLat, wgsLon);
 29         return { 'lat': wgsLat + d.lat, 'lon': wgsLon + d.lon };
 30     },
 31     //GCJ-02 to WGS-84
 32     gcj_decrypt: function (gcjLat, gcjLon) {
 33         if (this.outOfChina(gcjLat, gcjLon))
 34             return { 'lat': gcjLat, 'lon': gcjLon };
 35 
 36         var d = this.delta(gcjLat, gcjLon);
 37         return { 'lat': gcjLat - d.lat, 'lon': gcjLon - d.lon };
 38     },
 39     //GCJ-02 to WGS-84 exactly
 40     gcj_decrypt_exact: function (gcjLat, gcjLon) {
 41         var initDelta = 0.01;
 42         var threshold = 0.000000001;
 43         var dLat = initDelta, dLon = initDelta;
 44         var mLat = gcjLat - dLat, mLon = gcjLon - dLon;
 45         var pLat = gcjLat + dLat, pLon = gcjLon + dLon;
 46         var wgsLat, wgsLon, i = 0;
 47         while (1) {
 48             wgsLat = (mLat + pLat) / 2;
 49             wgsLon = (mLon + pLon) / 2;
 50             var tmp = this.gcj_encrypt(wgsLat, wgsLon)
 51             dLat = tmp.lat - gcjLat;
 52             dLon = tmp.lon - gcjLon;
 53             if ((Math.abs(dLat) < threshold) && (Math.abs(dLon) < threshold))
 54                 break;
 55 
 56             if (dLat > 0) pLat = wgsLat; else mLat = wgsLat;
 57             if (dLon > 0) pLon = wgsLon; else mLon = wgsLon;
 58 
 59             if (++i > 10000) break;
 60         }
 61         //console.log(i);
 62         return { 'lat': wgsLat, 'lon': wgsLon };
 63     },
 64     //GCJ-02 to BD-09
 65     bd_encrypt: function (gcjLat, gcjLon) {
 66         var x = gcjLon, y = gcjLat;
 67         var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * this.x_pi);
 68         var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * this.x_pi);
 69         bdLon = z * Math.cos(theta) + 0.0065;
 70         bdLat = z * Math.sin(theta) + 0.006;
 71         return { 'lat': bdLat, 'lon': bdLon };
 72     },
 73     //BD-09 to GCJ-02
 74     bd_decrypt: function (bdLat, bdLon) {
 75         var x = bdLon - 0.0065, y = bdLat - 0.006;
 76         var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * this.x_pi);
 77         var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * this.x_pi);
 78         var gcjLon = z * Math.cos(theta);
 79         var gcjLat = z * Math.sin(theta);
 80         return { 'lat': gcjLat, 'lon': gcjLon };
 81     },
 82     //WGS-84 to Web mercator
 83     //mercatorLat -> y mercatorLon -> x
 84     mercator_encrypt: function (wgsLat, wgsLon) {
 85         var x = wgsLon * 20037508.34 / 180.;
 86         var y = Math.log(Math.tan((90. + wgsLat) * this.PI / 360.)) / (this.PI / 180.);
 87         y = y * 20037508.34 / 180.;
 88         return { 'lat': y, 'lon': x };
 89         /*
 90         if ((Math.abs(wgsLon) > 180 || Math.abs(wgsLat) > 90))
 91         return null;
 92         var x = 6378137.0 * wgsLon * 0.017453292519943295;
 93         var a = wgsLat * 0.017453292519943295;
 94         var y = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
 95         return {'lat' : y, 'lon' : x};
 96         //*/
 97     },
 98     // Web mercator to WGS-84
 99     // mercatorLat -> y mercatorLon -> x
100     mercator_decrypt: function (mercatorLat, mercatorLon) {
101         var x = mercatorLon / 20037508.34 * 180.;
102         var y = mercatorLat / 20037508.34 * 180.;
103         y = 180 / this.PI * (2 * Math.atan(Math.exp(y * this.PI / 180.)) - this.PI / 2);
104         return { 'lat': y, 'lon': x };
105         /*
106         if (Math.abs(mercatorLon) < 180 && Math.abs(mercatorLat) < 90)
107         return null;
108         if ((Math.abs(mercatorLon) > 20037508.3427892) || (Math.abs(mercatorLat) > 20037508.3427892))
109         return null;
110         var a = mercatorLon / 6378137.0 * 57.295779513082323;
111         var x = a - (Math.floor(((a + 180.0) / 360.0)) * 360.0);
112         var y = (1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * mercatorLat) / 6378137.0)))) * 57.295779513082323;
113         return {'lat' : y, 'lon' : x};
114         //*/
115     },
116     // two point's distance
117     distance: function (latA, lonA, latB, lonB) {
118         var earthR = 6371000.;
119         var x = Math.cos(latA * this.PI / 180.) * Math.cos(latB * this.PI / 180.) * Math.cos((lonA - lonB) * this.PI / 180);
120         var y = Math.sin(latA * this.PI / 180.) * Math.sin(latB * this.PI / 180.);
121         var s = x + y;
122         if (s > 1) s = 1;
123         if (s < -1) s = -1;
124         var alpha = Math.acos(s);
125         var distance = alpha * earthR;
126         return distance;
127     },
128     outOfChina: function (lat, lon) {
129         if (lon < 72.004 || lon > 137.8347)
130             return true;
131         if (lat < 0.8293 || lat > 55.8271)
132             return true;
133         return false;
134     },
135     transformLat: function (x, y) {
136         var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
137         ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
138         ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;
139         ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;
140         return ret;
141     },
142     transformLon: function (x, y) {
143         var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
144         ret += (20.0 * Math.sin(6.0 * x * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
145         ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;
146         ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;
147         return ret;
148     }
149 };
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM