基于ArcGIS API for JavaScript加載百度各種類型切片地圖
原創(chuàng)giao00000 最后發(fā)布于2019-03-24 23:01:13 閱讀數(shù) 923? 收藏
展開
文章目錄
應(yīng)用場景
需求分析
效果圖
實現(xiàn)代碼
原理解讀
應(yīng)用場景
部分項目基于ArcGIS平臺,但是甲方只提供部分矢量數(shù)據(jù),用作底圖的地形圖數(shù)據(jù)沒有,表示可以使用百度地圖作為底圖。所以才會有使用ArcGIS JS API加載百度地圖的這種特殊需求。
需求分析
上面描述的需求場景有兩種解決方案:
下載指定區(qū)域的百度地圖(.tif格式),將下載好的地圖在ArcMap中處理之后,通過ArcGIS Server發(fā)布成切片地圖服務(wù),之后就可以直接用API加載了。問題在于需要借助地圖下載工具下載數(shù)據(jù),數(shù)據(jù)量可能會比較大。
基于ArcGIS API for JavaScript中的TiledMapServiceLayer類進(jìn)行擴(kuò)展,直接使用百度地圖在線切片。優(yōu)勢:數(shù)據(jù)無需單獨(dú)下載,可以使用百度各種類型切片地圖,如道路、午夜黑等。
這里通過方案二入手。
效果圖
實現(xiàn)代碼
封裝模塊:BaiduLayer.js
define(["dojo/_base/declare", "esri/layers/TiledMapServiceLayer", "esri/geometry/Extent", "esri/SpatialReference", "esri/layers/TileInfo"],
? function (declare, TiledMapServiceLayer, Extent, SpatialReference, TileInfo) {
? ? return declare(TiledMapServiceLayer, {
? ? ? layertype: "midNightStyle", //圖層類型
? ? ? baiduAK: "1H8Dhi2pGmOMYbN4EcaAGr1rv8f7Gmjz", //百度開發(fā)密鑰
? ? ? // 構(gòu)造函數(shù)
? ? ? constructor: function (properties) {
? ? ? ? this.spatialReference = new SpatialReference({
? ? ? ? ? wkid: 102100? //webMercator投影
? ? ? ? });
? ? ? ? declare.safeMixin(this, properties);
? ? ? ? // 圖層提供的起始顯示范圍以及整個圖層的地理范圍
? ? ? ? // this.fullExtent = new Extent(-16777360, -16797630, 16777360, 16797630, this.spatialReference);
? ? ? ? this.fullExtent = new Extent(-20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787, this.spatialReference);
? ? ? ? this.initialExtent = new Extent(5916776.8, 1877209.3, 19242502.6, 7620381.8, this.spatialReference);
? ? ? ? // 圖層提供的切片信息
? ? ? ? this.tileInfo = new TileInfo({
? ? ? ? ? "rows": 256,
? ? ? ? ? "cols": 256,
? ? ? ? ? "compressionQuality": 0,
? ? ? ? ? "origin": {
? ? ? ? ? ? "x": -16777360, //濟(jì)南適用
? ? ? ? ? ? "y": 16802960
? ? ? ? ? },
? ? ? ? ? "spatialReference": {
? ? ? ? ? ? "wkid": 102100
? ? ? ? ? },
? ? ? ? ? "lods": [{
? ? ? ? ? ? ? "level": 0,
? ? ? ? ? ? ? "resolution": 131072,
? ? ? ? ? ? ? "scale": 131072 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 1,
? ? ? ? ? ? ? "resolution": 65536,
? ? ? ? ? ? ? "scale": 65536 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 2,
? ? ? ? ? ? ? "resolution": 32768,
? ? ? ? ? ? ? "scale": 32768 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 3,
? ? ? ? ? ? ? "resolution": 16384,
? ? ? ? ? ? ? "scale": 16384 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 4,
? ? ? ? ? ? ? "resolution": 8192,
? ? ? ? ? ? ? "scale": 8192 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 5,
? ? ? ? ? ? ? "resolution": 4096,
? ? ? ? ? ? ? "scale": 4096 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 6,
? ? ? ? ? ? ? "resolution": 2048,
? ? ? ? ? ? ? "scale": 2048 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 7,
? ? ? ? ? ? ? "resolution": 1024,
? ? ? ? ? ? ? "scale": 1024 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 8,
? ? ? ? ? ? ? "resolution": 512,
? ? ? ? ? ? ? "scale": 512 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 9,
? ? ? ? ? ? ? "resolution": 256,
? ? ? ? ? ? ? "scale": 256 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 10,
? ? ? ? ? ? ? "resolution": 128,
? ? ? ? ? ? ? "scale": 128 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 11,
? ? ? ? ? ? ? "resolution": 64,
? ? ? ? ? ? ? "scale": 64 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 12,
? ? ? ? ? ? ? "resolution": 32,
? ? ? ? ? ? ? "scale": 32 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 13,
? ? ? ? ? ? ? "resolution": 16,
? ? ? ? ? ? ? "scale": 16 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 14,
? ? ? ? ? ? ? "resolution": 8,
? ? ? ? ? ? ? "scale": 8 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 15,
? ? ? ? ? ? ? "resolution": 4,
? ? ? ? ? ? ? "scale": 4 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 16,
? ? ? ? ? ? ? "resolution": 2,
? ? ? ? ? ? ? "scale": 2 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 17,
? ? ? ? ? ? ? "resolution": 1,
? ? ? ? ? ? ? "scale": 1 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 18,
? ? ? ? ? ? ? "resolution": 0.5,
? ? ? ? ? ? ? "scale": 0.5 * 256
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? "level": 19,
? ? ? ? ? ? ? "resolution": 0.25,
? ? ? ? ? ? ? "scale": 0.25 * 256
? ? ? ? ? ? }
? ? ? ? ? ]
? ? ? ? });
? ? ? ? // 設(shè)置圖層的loaded屬性,并觸發(fā)onLoad事件
? ? ? ? this.loaded = true;
? ? ? ? this.onLoad(this);
? ? ? },
? ? ? getTileUrl: function (level, row, col) {
? ? ? ? var url = "";
? ? ? ? var zoom = level - 1;
? ? ? ? var offsetX = Math.pow(2, zoom);
? ? ? ? var offsetY = offsetX - 1;
? ? ? ? var numX = col - offsetX;
? ? ? ? var numY = (-row) + offsetY;
? ? ? ? zoom = level + 1;
? ? ? ? var num = (col + row) % 8 + 1;
? ? ? ? switch (this.layertype) {
? ? ? ? ? case "road":
? ? ? ? ? ? url = "http://online1.map.bdimg.com/tile/?qt=tile&x=" + numX + "&y=" + numY + "&z=" + zoom + "&styles=pl";
? ? ? ? ? ? break;
? ? ? ? ? case "st":
? ? ? ? ? ? //url = "http://q"+num+".baidu.com/it/u=x="+numX+";y="+numY+";z="+zoom+";v=009;type=sate&fm=46";
? ? ? ? ? ? url = "http://shangetu" + num + ".map.bdimg.com/it/u=x=" + numX + ";y=" + numY + ";z=" + zoom + ";v=009;type=sate&fm=46";
? ? ? ? ? ? break;
? ? ? ? ? case "label":
? ? ? ? ? ? url = "http://online1.map.bdimg.com/tile/?qt=tile&x=" + numX + "&y=" + numY + "&z=" + zoom + "&styles=sl&v=020";
? ? ? ? ? ? break;
? ? ? ? ? case "simpleStyle":
? ? ? ? ? ? url = "http://api1.map.bdimg.com/customimage/tile?&x=" + numX + "&y=" + numY + "&z=" + zoom + "&ak=" + this.baiduAK + "&styles=t%3Aroad%7Ce%3Aall%7Cl%3A20%2Ct%3Ahighway%7Ce%3Ag%7Cc%3A%23f49935%2Ct%3Arailway%7Ce%3Aall%7Cv%3Aoff%2Ct%3Alocal%7Ce%3Al%7Cv%3Aoff%2Ct%3Awater%7Ce%3Aall%7Cc%3A%23d1e5ff%2Ct%3Apoi%7Ce%3Al%7Cv%3Aoff";
? ? ? ? ? ? break;
? ? ? ? ? case "grassGreenStyle":
? ? ? ? ? ? url = "http://api0.map.bdimg.com/customimage/tile?&x=" + numX + "&y=" + numY + "&z=" + zoom + "&ak=" + this.baiduAK + "&styles=t%3Awater%7Ce%3Aall%7Cc%3A%2372b8fe%2Ct%3Aroad%7Ce%3Ag.f%7Cc%3A%23ffffff%2Ct%3Aroad%7Ce%3Ag.s%7Cc%3A%23bababa%2Ct%3Aroad%7Ce%3Al.t.f%7Cc%3A%23767676%2Ct%3Aroad%7Ce%3Al.t.s%7Cc%3A%23ffffff%2Ct%3Aland%7Ce%3Aall%7Cc%3A%23b8cb93";
? ? ? ? ? ? break;
? ? ? ? ? case "midNightStyle":
? ? ? ? ? ? url = "http://api1.map.bdimg.com/customimage/tile?&x=" + numX + "&y=" + numY + "&z=" + zoom + "&ak=" + this.baiduAK + "&styles=t%3Awater%7Ce%3Aall%7Cc%3A%23021019%2Ct%3Ahighway%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Ahighway%7Ce%3Ag.s%7Cc%3A%23147a92%2Ct%3Aarterial%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Aarterial%7Ce%3Ag.s%7Cc%3A%230b3d51%2Ct%3Alocal%7Ce%3Ag%7Cc%3A%23000000%2Ct%3Aland%7Ce%3Aall%7Cc%3A%2308304b%2Ct%3Arailway%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Arailway%7Ce%3Ag.s%7Cc%3A%2308304b%2Ct%3Asubway%7Ce%3Ag%7Cl%3A-70%2Ct%3Abuilding%7Ce%3Ag.f%7Cc%3A%23000000%2Ct%3Aall%7Ce%3Al.t.f%7Cc%3A%23857f7f%2Ct%3Aall%7Ce%3Al.t.s%7Cc%3A%23000000%2Ct%3Abuilding%7Ce%3Ag%7Cc%3A%23022338%2Ct%3Agreen%7Ce%3Ag%7Cc%3A%23062032%2Ct%3Aboundary%7Ce%3Aall%7Cc%3A%231e1c1c%2Ct%3Amanmade%7Ce%3Ag%7Cc%3A%23022338%2Ct%3Apoi%7Ce%3Aall%7Cv%3Aoff%2Ct%3Aall%7Ce%3Al.i%7Cv%3Aoff%2Ct%3Aall%7Ce%3Al.t.f%7Cv%3Aon%7Cc%3A%232da0c6";
? ? ? ? ? ? break;
? ? ? ? ? case "darkStyle":
? ? ? ? ? ? url = "http://api2.map.bdimg.com/customimage/tile?&x=" + numX + "&y=" + numY + "&z=" + zoom + "&ak=" + this.baiduAK + "&styles=t%3Aland%7Ce%3Ag%7Cc%3A%23212121%2Ct%3Abuilding%7Ce%3Ag%7Cc%3A%232b2b2b%2Ct%3Ahighway%7Ce%3Aall%7Cl%3A-42%7Cs%3A-91%2Ct%3Aarterial%7Ce%3Ag%7Cl%3A-77%7Cs%3A-94%2Ct%3Agreen%7Ce%3Ag%7Cc%3A%231b1b1b%2Ct%3Awater%7Ce%3Ag%7Cc%3A%23181818%2Ct%3Asubway%7Ce%3Ag.s%7Cc%3A%23181818%2Ct%3Arailway%7Ce%3Ag%7Cl%3A-52%2Ct%3Aall%7Ce%3Al.t.s%7Cc%3A%23313131%2Ct%3Aall%7Ce%3Al.t.f%7Cc%3A%238b8787%2Ct%3Amanmade%7Ce%3Ag%7Cc%3A%231b1b1b%2Ct%3Alocal%7Ce%3Ag%7Cl%3A-75%7Cs%3A-91%2Ct%3Asubway%7Ce%3Ag%7Cl%3A-65%2Ct%3Arailway%7Ce%3Aall%7Cl%3A-40%2Ct%3Aboundary%7Ce%3Ag%7Cc%3A%238b8787%7Cl%3A-29%7Cw%3A1";
? ? ? ? ? ? break;
? ? ? ? ? default:
? ? ? ? ? ? url = "http://online1.map.bdimg.com/tile/?qt=tile&x=" + numX + "&y=" + numY + "&z=" + zoom + "&styles=pl";
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? return url;
? ? ? }
? ? });
? }
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
index.html
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <title>ArcGIS調(diào)用百度在線切片</title>
</head>
<link rel="stylesheet" >
<style>
? ? html, body, #map {
? ? ? ? height: 100%;
? ? ? ? margin: 0;
? ? ? ? padding: 0;
? ? }
</style>
<script>
? ? var package_path = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/'));
? ? var dojoConfig = {
? ? ? ? // The locationPath logic below may look confusing but all its doing is
? ? ? ? // enabling us to load the api from a CDN and load local modules from the correct location.
? ? ? ? packages: [{
? ? ? ? ? ? name: "modules",
? ? ? ? ? ? location: package_path + '/modules'
? ? ? ? }]
? ? };
</script>
<script src="https://js.arcgis.com/3.27/"></script>
<script>
? ? require([
? ? ? ? "esri/map",
? ? ? ? "modules/BaiduLayer",
? ? ? ? "dojo/domReady!"], function(Map,BaiduLayer) {
? ? ? ? var map = new Map("map");
? ? ? ? var options = {
? ? ? ? ? ? layertype: "darkStyle"
? ? ? ? }
? ? ? ? var layer = new BaiduLayer(options);
? ? ? ? map.addLayer(layer);
? ? });
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
原理解讀
以下為個人見解,如有不當(dāng)敬請指出,核心代碼主要在getTile這塊:
getTileUrl: function (level, row, col) {
? ? ? ? var url = "";
? ? ? ? var zoom = level - 1;
? ? ? ? var offsetX = Math.pow(2, zoom);
? ? ? ? var offsetY = offsetX - 1;
? ? ? ? var numX = col - offsetX;
? ? ? ? var numY = (-row) + offsetY;
? ? ? ? zoom = level + 1;
? ? ? ? var num = (col + row) % 8 + 1;
? ? ? ? url = "http://api2.map.bdimg.com/customimage/tile?&x=" + numX + "&y=" + numY + "&z=" + zoom + "&ak=" + this.baiduAK + '太長了省略';
? ? ? ? return url;
}
1
2
3
4
5
6
7
8
9
10
11
12
關(guān)鍵在于切片坐標(biāo)的轉(zhuǎn)換,通過下圖可以看到ArcGIS切片坐標(biāo)定義方式:
ArcGIS的切片坐標(biāo)定義方式是從左上角開始,按照行列號劃分。高德地圖、Open Street Map、Google地圖同樣采用此種切片方式。
百度地圖切片坐標(biāo)定義方式如下圖:
兩者的切片坐標(biāo)系不太一樣,要想將切片放到正確的位置就要進(jìn)行坐標(biāo)轉(zhuǎn)換了,公式已經(jīng)在代碼里面里了,就是簡單的數(shù)學(xué)轉(zhuǎn)換。關(guān)于國內(nèi)主要地圖瓦片坐標(biāo)系定義及計算原理
源代碼下載地址:https://download.csdn.net/download/wml00000/11055976
————————————————
版權(quán)聲明:本文為CSDN博主「giao00000」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wml00000/article/details/88784277