本案例使用Mapbox GL JavaScript库进行加载全球3D建筑。
文章目录
- 1. 引入 CDN 链接
- 2. 创建地图
- 3. 监听地图加载完成事件
- 3.1. 获取地图的样式中的图层
- 3.2. 查找图层
- 3.3. 添加三维建筑图层
- 4. 演示效果
- 5. 代码实现
1. 引入 CDN 链接
<!-- 1.引入CDN链接 -->
<script src="https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js"></script>
<link
href="https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css"
rel="stylesheet"
/>
2. 创建地图
我们创建了一个Mapbox GL JS地图实例,设置了地图的容器、默认的地图风格、中心点坐标、地图级别、地图俯仰角、地球旋转角度以及启用抗锯齿功能。
const map = new mapboxgl.Map({
container: "map", //地图容器
style: "mapbox://styles/mapbox/light-v11", //地图样式
center: [-74.0066, 40.7135], //地图中心
zoom: 15.5, //缩放级别
pitch: 45, //地图俯仰角
bearing: -17.6, //地图旋转角度
antialias: true, //启用抗锯齿功能
});
3. 监听地图加载完成事件
3.1. 获取地图的样式中的图层
const layers = map.getStyle().layers;
3.2. 查找图层
查找图层中类型为symbol并且有text-field属性的图层。
// 3.2 查找图层
const labelLayerId = layers.find(
(layer) => layer.type === "symbol" && layer.layout["text-field"]
).id;
3.3. 添加三维建筑图层
将三维建筑数据层添加到地图中,并应用一些样式来表现数据。
- 首先,代码定义了一个图层对象,包括所需的属性,如 ID、数据源、图层名称、过滤器、类型和最小缩放级别。
- 接着,为图层对象定义了一个 paint 属性,用于定义图层的样式。这里的样式包括填充颜色的透明度(opacity)、三维建筑的高度和基线。
- 使用
"interpolate"
表达式来平滑地过渡效果,当用户缩放地图时,三维建筑的高度和基线会随着地图的放大而增加。 - 最后,将图层对象添加到地图中,并指定标签层labelLayerId。
// 3.3 添加三维建筑图层
map.addLayer(
{
id: "add-3d-buildings",
source: "composite",
"source-layer": "building",
filter: ["==", "extrude", "true"],
type: "fill-extrusion",
minzoom: 15,
paint: {
"fill-extrusion-color": "#aaa",
// Use an 'interpolate' expression to
// add a smooth transition effect to
// the buildings as the user zooms in.
// 图层高度
"fill-extrusion-height": [
"interpolate",
["linear"],
["zoom"],
1,
0,
8,
["get", "height"],
],
// 离地高度
"fill-extrusion-base": [
"interpolate",
["linear"],
["zoom"],
1,
0,
8,
["get", "min_height"],
],
"fill-extrusion-opacity": 0.9,
},
},
labelLayerId
);
4. 演示效果
5. 代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 1.引入CDN链接 -->
<script src="https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js"></script>
<link
href="https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css"
rel="stylesheet"
/>
<title>加载全球3D建筑</title>
<style>
* {
margin: 0;
padding: 0;
}
#map {
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
// 2.创建地图
window.onload = () => {
// 注册token
mapboxgl.accessToken =
"pk.eyJ1IjoiY2hlbmdjaGFvODg2NiIsImEiOiJjbGhzcWowMHUwYTNyM2VwNXZhaXhjd3Q4In0.FEh2q7sEW88Z1B5GcK_TDg";
// 初始化地图对象
const map = new mapboxgl.Map({
container: "map", //地图容器
style: "mapbox://styles/mapbox/light-v11", //地图样式
center: [-74.0066, 40.7135], //地图中心
zoom: 15.5, //缩放级别
pitch: 45, //地图俯仰角
bearing: -17.6, //地图旋转角度
antialias: true, //启用抗锯齿功能
});
// 3.监听地图加载完成事件
map.on("style.load", () => {
// Insert the layer beneath any symbol layer.
// 3.1 获取地图的样式中的图层
const layers = map.getStyle().layers;
// 3.2 查找图层
// 查找图层中类型为symbol并且有text-field属性的图层
const labelLayerId = layers.find(
(layer) => layer.type === "symbol" && layer.layout["text-field"]
).id;
// The 'building' layer in the Mapbox Streets
// vector tileset contains building height data
// from OpenStreetMap.
// 3.3 添加三维建筑图层
map.addLayer(
{
id: "add-3d-buildings",
source: "composite",
"source-layer": "building",
filter: ["==", "extrude", "true"],
type: "fill-extrusion",
minzoom: 15,
paint: {
"fill-extrusion-color": "#aaa",
// Use an 'interpolate' expression to
// add a smooth transition effect to
// the buildings as the user zooms in.
// 图层高度
"fill-extrusion-height": [
"interpolate",
["linear"],
["zoom"],
1,
0,
8,
["get", "height"],
],
// 离地高度
"fill-extrusion-base": [
"interpolate",
["linear"],
["zoom"],
1,
0,
8,
["get", "min_height"],
],
"fill-extrusion-opacity": 0.9,
},
},
labelLayerId
);
});
};
</script>
</body>
</html>