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

 

posted @ 2015-11-16 12:12  章先生和陶小姐  阅读(12898)  评论(5编辑  收藏  举报