此示例渲染了一个使用 Azure 地图 API(原 Bing)作为数据源的瓦片图层。Processing API 需要密钥。上方表单可用于输入您的主密钥。您可以按照以下文档获取自己的 Azure 地图密钥:https://learn.microsoft.com/en-us/azure/azure-maps/quick-demo-map-app。

由于需要绑定微软指定的信用卡,注册卡在了这里,尴尬,所以没发完成注册,只能作罢。

main.js代码如下:

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
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import {useGeographic} from 'ol/proj.js';
import ImageTile from 'ol/source/ImageTile.js';

useGeographic();

const someTilesetId = [
'microsoft.imagery',
'microsoft.base.road',
'microsoft.base.darkgrey',
];

const baseUrl =
'https://atlas.microsoft.com/map/tile?zoom={z}&x={x}&y={y}&tileSize=256&language=EN&&api-version=2.0';

let subscriptionKey, currentLayer, map;

document.getElementById('auth-form').addEventListener('submit', (event) => {
event.preventDefault();
subscriptionKey = document.getElementById('secret').value.trim();

map = new Map({
target: 'map',
view: new View({
center: [2.35, 48.85],
zoom: 12,
}),
});
document.getElementById('auth-interface').style.display = 'none';
document.getElementById('map-container').style.display = 'block';

document.querySelectorAll('.layer-btn').forEach((btn) => {
btn.addEventListener('click', () => {
updateLayer(Number(btn.value));
});
});

updateLayer(0);
});

function updateLayer(index) {
currentLayer = new TileLayer({
source: new ImageTile({
url: `${baseUrl}&subscription-key=${subscriptionKey}&tilesetId=${someTilesetId[index]}`,
crossOrigin: 'anonymous',
attributions: ${new Date().getFullYear()} TomTom, Microsoft`,
}),
});

map.addLayer(currentLayer);

// 地图渲染完成后删除之前的图层
map.once('rendercomplete', () => {
for (const layer of map.getLayers().getArray()) {
if (layer === currentLayer) {
break; // 跳过新添加的图层
}
map.removeLayer(layer);
}
});

// 更新瓦片集按钮的状态
document.querySelectorAll('.layer-btn').forEach((btn) => {
btn.classList.toggle('active', btn.value == index);
});
}

界面布局文件index.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
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Azure Maps</title>
<link rel="stylesheet" href="node_modules/ol/ol.css">
<style>
.map {
width: 100%;
height: 400px;
}
#auth-interface {
background: #f5f5f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
}
#map-container {
display: none;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
#map {
width: 100%;
height: 500px;
}
.layer-switcher {
display: flex;
gap: 10px;
padding: 15px;
background: #f9f9f9;
border-top: 1px solid #eee;
}
.layer-btn {
padding: 8px 15px;
background: #fff;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
}
.layer-btn:hover {
background: #f0f0f0;
}
.layer-btn.active {
background: #4CAF50;
color: white;
border-color: #4CAF50;
}
#auth-form {
display: flex;
gap: 10px;
}
#secret {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
button[type="submit"] {
padding: 10px 20px;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="auth-interface">
<form id="auth-form">
<input type="text" id="secret" placeholder="Your Azure Maps primary key" required>
<button type="submit">Ok show the map</button>
</form>
</div>

<div id="map-container">
<div id="map"></div>
<div class="layer-switcher">
<button class="layer-btn active" value="0">Satellite</button>
<button class="layer-btn" value="1">Roads</button>
<button class="layer-btn" value="2">Dark</button>
</div>
</div>

<script type="module" src="main.js"></script>
</body>
</html>

总结

  1. ol/proj模块下的useGeographic():它是一个便捷的全局设置函数,用于将 OpenLayers 的默认投影切换到 EPSG:4326(经纬度坐标系),简化基于地理坐标的地图开发。调用时需在地图初始化之前,确保坐标输入以经纬度格式提供。默认情况下,OpenLayers 使用 Web 墨卡托(EPSG:3857),单位为米,适合大多数 Web 地图应用。调用 useGeographic() 后,坐标系变为 EPSG:4326,单位为度,适合地理坐标场景。
  2. Map对象的getAllLayers()方法与getLayers()方法区别:
  • getAllLayers():返回地图上所有图层的扁平化数组,包括图层组内的所有子图层。递归遍历图层组,提取所有子图层,形成一个扁平的图层列表。而且返回的是静态数组,不是动态集合,无法直接监听变化。
  • getLayers():返回地图的顶层图层集合(ol.Collection),仅包含直接添加到地图中的图层。如果地图包含图层组(ol.layer.Group),不会自动展开组内的子图层,仅返回组本身。返回的集合是动态的,可以监听其变化(例如图层添加或移除)。