Openlayers3在线加载天地图浙江

标签: Openlayers 分类: Gis 创建时间:2019-09-19 07:07:02 更新时间:2024-11-15 10:49:43

由于我工作的关系,说白了我上一家公司就是做天地图浙江的,所以我对天地图浙江加载还是略懂一点的,也不仅仅限于加载天地图浙江吧,其实使用openlayer加载天地图也是一样的。直接上代码:

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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
// 定义对象拼接方法
Object.defineProperty(Object, "assign", {
enumerable: false,
configurable: true,
writable: true,
value: function (target, firstSource) {
"use strict";
if (target === undefined || target === null)
throw new TypeError("Cannot convert first argument to object");
var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) continue;
var keysArray = Object.keys(Object(nextSource));
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) to[nextKey] = nextSource[nextKey];
}
}
return to;

}
});

var projection = ol.proj.get('EPSG:4326');
var maxLevel = 20
function TMap(id, center,level,maptype) {
center=center||[120.158, 30.267];
level=level||16;
maptype=maptype||"img"
ol.Map.call(this,{
logo:false,
target:id,
view:new ol.View({
center: center,
projection: projection,
zoom: level,
maxZoom: maxLevel,
minZoom: 2
})
});
this.layerArray=[];//地图图层数组
this.events={};//地图事件列表
this.maptype = maptype;
this.level=level;
this.center=center;
if(typeof this.setOnlineMapType == "function"){
this.setOnlineMapType(maptype, center, level)
}

}
ol.inherits(TMap, ol.Map);
//合并原型链
Object.assign(TMap.prototype, {
maxLevel: 20,
projection: projection,
origin: (function () {
let projection = ol.proj.get('EPSG:4326')
let projectionExtent = projection.getExtent()
return ol.extent.getTopLeft(projectionExtent)
})(),
resolutions: [1.40625, 0.703125, 0.3515625, 0.17578125, 0.087890625, 0.0439453125, 0.02197265625, 0.010986328125,
0.0054931640625, 0.00274658203125, 0.001373291015625, 0.0006866455078125, 0.00034332275390625, 0.000171661376953125,
0.0000858306884765625, 0.00004291534423828125, 0.000021457672119140625, 0.000010728836059570312, 0.000005364418029785156,
0.000002682209014892578, 0.000001341104507446289],
matrixIds: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
mapConfigObject:[
{
"id": "59d77b2cdc8640b9b7f467f7110d43b1",
"created": 1537885383338,
"updated": 1558515675027,
"name": "2018年影像",
"zindex": 0,
"min": 7,
"max": 18,
"zoomoffset": 0,
"ogctype": "wmts",
"url": "http://ditu.zj.cn/services/wmts/imgmap_latest",
"version": "1.0.0",
"layer": "imgmap_latest",
"format": "image/jpgpng",
"style": "default",
"wmts_tile_matrixset": "default028mm",
"tdtcode": "zhejiang",
"baselayer": true,
"tags": "detail",
"fname": "浙江省",
"copyright": "浙江省地理信息公共服务平台",
"lon": 120.148095,
"lat": 30.269723
},
{
"id": "750d9ba37fb3455d9e167f32448f734e",
"created": 1463737433798,
"updated": 1465807537223,
"name": "2000年左右影像",
"zindex": 0,
"min": 7,
"max": 18,
"zoomoffset": 0,
"ogctype": "wmts",
"url": "http://srv.zjditu.cn/services/wmts/imgmap_ls1998-2003",
"version": "1.0.0",
"layer": "imgmap_ls1998-2003",
"format": "image/jpgpng",
"style": "default",
"wmts_tile_matrixset": "default028mm",
"tdtcode": "zhejiang",
"baselayer": true,
"tags": "img_2000",
"fname": "浙江省",
"copyright": "浙江省地理信息公共服务平台",
"lon": 120.148095,
"lat": 30.269723
},
{
"id": "cf3cde7bb8a64b6ba44cd6c980e642fa",
"created": 1459171567368,
"updated": 1552494146855,
"name": "ZJDOM2W1",
"zindex": 2,
"min": 7,
"max": 20,
"zoomoffset": 0,
"ogctype": "wmts",
"url": "http://srv{s}.zjditu.cn/ZJDOM_2D/wmts",
"domain": "0,1,2,3",
"version": "1.0.0",
"layer": "imgmap",
"format": "image/jpgpng",
"style": "default",
"wmts_tile_matrixset": "default028mm",
"tdtcode": "zhejiang",
"baselayer": true,
"tags": "img",
"fname": "浙江省",
"copyright": "浙江省地理信息公共服务平台",
"lon": 120.148095,
"lat": 30.269723
},
{
"id": "802a4f81b026493ba5d9a2031a0b5687",
"created": 1465807667085,
"updated": 1465810435553,
"name": "60年代影像",
"zindex": 0,
"min": 8,
"max": 18,
"zoomoffset": 0,
"ogctype": "wmts",
"url": "http://srv.zjditu.cn/services/wmts/imgmap_60s",
"version": "1.0.0",
"layer": "imgmap_60s",
"format": "image/jpgpng",
"style": "default",
"wmts_tile_matrixset": "default028mm",
"tdtcode": "zhejiang",
"baselayer": true,
"tags": "img_60",
"fname": "浙江省",
"copyright": "浙江省地理信息公共服务平台",
"lon": 120.148095,
"lat": 30.269723
},
{
"id": "d56fae04a159467db1b9ea7c5911b645",
"created": 1459171567419,
"updated": 1552495700458,
"name": "zjemap_anno",
"zindex": 3,
"min": 7,
"max": 20,
"zoomoffset": 0,
"ogctype": "wmts",
"url": "http://srv{s}.zjditu.cn/ZJEMAPANNO_2D/wmts",
"domain": "0,1,2,3",
"version": "1.0.0",
"layer": "TDT_ZJEMAPANNO",
"format": "image/jpgpng",
"style": "default",
"wmts_tile_matrixset": "default028mm",
"tdtcode": "zhejiang",
"baselayer": true,
"tags": "road,label",
"fname": "浙江省",
"copyright": "浙江省地理信息公共服务平台",
"lon": 120.148095,
"lat": 30.269723
},
{
"id": "2df2acdcee2a4e389a30f79813ac1d26",
"created": 1459171567570,
"updated": 1552494034118,
"name": "ZJDOM2W1anno",
"zindex": 3,
"min": 7,
"max": 20,
"zoomoffset": 0,
"ogctype": "wmts",
"url": "http://srv{s}.zjditu.cn/ZJDOMANNO_2D/wmts",
"domain": "0,1,2,3",
"version": "1.0.0",
"layer": "TDT_ZJIMGANNO",
"format": "image/jpgpng",
"style": "default",
"wmts_tile_matrixset": "default028mm",
"tdtcode": "zhejiang",
"baselayer": true,
"tags": "img,label",
"fname": "浙江省",
"copyright": "浙江省地理信息公共服务平台",
"lon": 120.148095,
"lat": 30.269723
},
{
"id": "d2d753f1dbf647489d5a514b4ef4f6dc",
"created": 1459171567560,
"updated": 1552495663879,
"name": "zjemap",
"zindex": 2,
"min": 7,
"max": 20,
"zoomoffset": 0,
"ogctype": "wmts",
"url": "http://srv{s}.zjditu.cn/ZJEMAP_2D/wmts",
"domain": "0,1,2,3",
"version": "1.0.0",
"layer": "TDT_ZJEMAP",
"format": "image/jpgpng",
"style": "default",
"wmts_tile_matrixset": "default028mm",
"tdtcode": "zhejiang",
"baselayer": true,
"tags": "road",
"fname": "浙江省",
"copyright": "浙江省地理信息公共服务平台",
"lon": 120.148095,
"lat": 30.269723
}
],
//获取地图类型
getMapType:function(){
return this.maptype;
},
//设置地图类型,分为emap、img、img_2000、img_70、img_60
setOnlineMapType:function(maptype, center, zoom) {
center=center||this.getView().getCenter();
zoom=zoom||this.getView().getZoom();
//请求天地图图层
var view = this.getView();
var bbox = view.calculateExtent().join(',');
var callName = "parseResponse" + new Date().getTime();
var url = "http://www.zjditu.cn/api/maplayer/current";
var tm=this;
$.ajax({
url: url,
dataType: 'jsonp',
jsonpCallback: callName,
jsonp: "_cb",
data:{
bbox:bbox,
zoom:zoom
},
success:function(response){
if (response.code === 200) {
tm.addOnlineMap(maptype, center, zoom, response.content);
}
},
error:function (error) {
console.log(error);
tm.addOnlineMap(maptype,center,zoom,tm.mapConfigObject);
}
});
},
//加载在线地图
addOnlineMap:function(maptype, center, level, mapConfigArray){
//如果当前的地图类型不是目标类型,则切换
var currentMapType =this.getMapType();
var targetTypeMap=null;//目标图层
var currentTypeMap=null;//当前图层
var mapColle = this.getLayers().getArray();
for (let i = 0; i < mapColle.length; i++) {
if (mapColle[i].get('name')===currentMapType) {
currentTypeMap=mapColle[i];
}
if(mapColle[i].get('name')===maptype) {
targetTypeMap=mapColle[i];
}
}
if (currentMapType !== maptype) {
currentTypeMap.setVisible(false);
}else {
targetTypeMap=currentTypeMap;
}
if (targetTypeMap) {
targetTypeMap.setVisible(true);
} else {
targetTypeMap = new ol.layer.Group({
name: maptype,
isBaseLayers: true,
layers: []
})
this.addLayer(targetTypeMap);
}
//判断哪些图层是当前图层数组中没有的,没有的加上,如果配置文件中没有,在当前图层数组中存在,则删除图层,不再加载
//如果执行请求current函数后,图层名称没有变化,则不进行下面的加载图层代码执行
var templayerNameArray=[];
for(var mapConfig of mapConfigArray) {
templayerNameArray.push(mapConfig.id);
}
var targetLayerColle=targetTypeMap.getLayers();
var targetLayers=targetLayerColle.getArray();
for(var i=0;i< targetLayers.length;i++) {
var layer=targetLayers[i];
var layerid=layer.get('id');
if(templayerNameArray.indexOf(layerid)>=0) {
continue;
}else {
targetLayerColle.remove(layer);
i--;
this.layerArray=_.without(this.layerArray, layerid);
}
}
//建立图层
var layerArray = [];
var layerCount = mapConfigArray.length;
for (let i = 0; i < layerCount; i++) {
var mapConfig = mapConfigArray[i];
// 排除18到20级,直接用省级
if(mapConfig.min==18&&mapConfig.max==20){
continue;
}

//如果存在同名图层,不再加载,避免了函数遍历
if (this.layerArray.indexOf(mapConfig.id)>=0) {
continue;
}
var url=mapConfig.url
if (url.indexOf('{s}') >= 0) {
url=url.replace('{s}', '{0-6}');
}
//判断加载的图层
var tagsFlag = -1;
switch (maptype) {
case 'img':
tagsFlag = mapConfig.tags.search(/img(?!.)|(?:img,label)/);
break;
case 'img_2000':
tagsFlag = mapConfig.tags.search(/img_2000/);
break;
case 'img_70':
tagsFlag = mapConfig.tags.search(/img_70/);
break;
case 'img_60':
tagsFlag = mapConfig.tags.search(/img_60/);
break;
default:
tagsFlag = mapConfig.tags.search(/road(?!.)|(?:road,label)/);
break;
}
if (tagsFlag >= 0) {
//var minR = mapConfig.max; //最小分辨率
//var maxR = mapConfig.min-1; //最大分辨率
var source= new ol.source.WMTS({
url: url,
id:mapConfig.id,
style: mapConfig.style,
format: mapConfig.format,
layer: mapConfig.layer,
matrixSet: mapConfig.wmts_tile_matrixset,
projection:projection,
tileGrid: new ol.tilegrid.WMTS({
origin: this.origin,
resolutions: this.resolutions,
matrixIds: this.matrixIds
})
});
//绑定瓦片加载失败时事件
source.on('tileloaderror', function(event) {
// console.log(event)
//let tile=event.tile
//let img=tile.getImage();
//img.src=require('../assets/images/zjbg.png');
});
// source.on("tileloadend",function (eve) {
// console.log(eve);
// })
var newlayer = new ol.layer.Tile({
name: mapConfig.name,
id:mapConfig.id,
group: maptype,
isBaseLayers: mapConfig.baselayer,
source:source,
//minResolution: this.resolutions[minR],
//maxResolution: this.resolutions[maxR],
zIndex: mapConfig.zindex ? mapConfig.zindex : 0
});
layerArray.push(newlayer);
//在地图上绘制自定义内容
newlayer.on("postcompose",function (event) {
var context=event.context;
context.save();
context.rotate(-45*Math.PI/180);

// 设置字体
context.font = "30px bold 黑体";
// 设置颜色
context.fillStyle = "#aaaaaa87";
// 设置水平对齐方式
context.textAlign = "center";
var width=context.canvas.width;
var height=context.canvas.height;
context.translate(-width,-height);
// 设置垂直对齐方式
context.textBaseline = "middle";
var text="这TM是什么鬼代码";
var drawCount=25;
// x方向循环绘制
for(var i=0;i<drawCount+2;i++){
var x=500*i;
for(var j=0;j<=drawCount+5;j++){
var y=300*j;
// 绘制文字(参数:要写的字,x坐标,y坐标)
context.fillText(text, x, y);
}
}
context.restore();
})
//存储图层名称
this.layerArray.push(mapConfig.id);
}
}
//加入图层组
targetTypeMap.getLayers().extend(layerArray);

this.maptype = maptype;
if (!this.events['moveend']) {
this.events['moveend'] = this.on('moveend', _.debounce((event) => {
let view=this.getView();
this.setOnlineMapType(this.getMapType(), view.getCenter(), view.getZoom());
}, 500));
}
return targetTypeMap;
},
//根据图层名称获取图层
getLayersByName:function(name) {
var mapColle = this.getLayers().getArray();
for (var i = 0; i < mapColle.length; i++) {
if (mapColle[i].get('name') === name) {
return mapColle[i];
}
}
return null;
},
//根据编号获取图层分辨率
getResolution:function (zoom) {
return this.resolutions[zoom];
}
});

其实这里和网上加载方式没什么区别,区别就在于我做了一个拐弯,就是通过获取当前地图范围,然后请求了一个不对外的方法获取到了当前地图范围内有哪些图层,然后把相关的图层加载进来,后来天地图浙江进行了省市县融合,其实可以省略这一步了,全部直接加载省里的地图就好了,只是因为遗留代码,所以就这么写了。上面是我抽象的一个TMap的一个类,在页面中只需要使用下面方法引入就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<title>天地图浙江</title>
<script src="./static/lib/jquery-3.3.1.min.js"></script>
<script src="./static/lib/jquery-migrate-1.2.1.min.js"></script>
<!--gis相关-->
<link rel="stylesheet" href="./static/lib/ol/ol.css">
</head>
<body>
<div id="allmap"></div>
</body>
<!--gis相关-->
<script src="./static/lib/ol/ol.js"></script>
<script type="text/javascript" src="./static/js/gis/lodash.min.js"></script>
<script type="text/javascript" src="./static/js/gis/TMap.js"></script>
<script>
// 加载地图
this.mainmap=new TMap('allmap',[120.349,30.34],18);
</script>
</html>

小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。