📌 学习目标
- 掌握实时更新要素的实现方法
- 理解相关API的使用
- 能够独立完成类似功能开发
🎯 核心概念
通过更新数据实时更改地图上的现有要素。
💻 完 整 代 码
代码示例
js
const map = new maplibregl.Map({
container: 'map',
style: 'https://tiles.openfreemap.org/styles/bright',
zoom: 0
});
map.on('load', () => {
// 这里我们使用D3来获取JSON数据,以便我们可以单独解析和使用它。
// 你可以使用任何请求方法(库或其他方式)。
d3.json(
'https://maplibre.org/maplibre-gl-js/docs/assets/hike.geojson',
(err, data) => {
if (err) throw err;
// 保存完整的坐标列表,用于后续使用
const coordinates = data.features[0].geometry.coordinates;
// 仅显示第一个坐标
data.features[0].geometry.coordinates = [coordinates[0]];
// 添加要素到地图中
map.addSource('trace', {type: 'geojson', data});
map.addLayer({
'id': 'trace',
'type': 'line',
'source': 'trace',
'paint': {
'line-color': 'yellow',
'line-opacity': 0.75,
'line-width': 5
}
});
// 设置视口
map.jumpTo({'center': coordinates[0], 'zoom': 14});
map.setPitch(30);
// 定时添加更多坐标并更新地图数据
let i = 0;
const timer = window.setInterval(() => {
if (i < coordinates.length) {
data.features[0].geometry.coordinates.push(
coordinates[i]
);
map.getSource('trace').setData(data);
map.panTo(coordinates[i]);
i++;
} else {
window.clearInterval(timer);
}
}, 10);
}
);
});
代码示例
html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Update a feature in realtime</title>
<meta property="og:description" content="通过更新数据实时更改地图上的现有要素。" />
<meta property="og:created" content="2025-06-25" />
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css' />
<script src='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script>
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://tiles.openfreemap.org/styles/bright',
zoom: 0
});
map.on('load', () => {
// 这里使用D3获取JSON数据,以便我们可以独立于GL JS在添加的源中使用它
// 进行解析和使用。您可以使用任何请求方法(库或其他方式)。
d3.json(
'https://maplibre.org/maplibre-gl-js/docs/assets/hike.geojson',
(err, data) => {
if (err) throw err;
// 保存完整的坐标列表供后续使用
const coordinates = data.features[0].geometry.coordinates;
// 首先只显示第一个坐标
data.features[0].geometry.coordinates = [coordinates[0]];
// 将其添加到地图
map.addSource('trace', {type: 'geojson', data});
map.addLayer({
'id': 'trace',
'type': 'line',
'source': 'trace',
'paint': {
'line-color': 'yellow',
'line-opacity': 0.75,
'line-width': 5
}
});
// 设置视口
map.jumpTo({'center': coordinates[0], 'zoom': 14});
map.setPitch(30);
// 定期从保存的列表中添加更多坐标并更新地图
let i = 0;
const timer = window.setInterval(() => {
if (i < coordinates.length) {
data.features[0].geometry.coordinates.push(
coordinates[i]
);
map.getSource('trace').setData(data);
map.panTo(coordinates[i]);
i++;
} else {
window.clearInterval(timer);
}
}, 10);
}
);
});
</script>
</body>
</html>
🔍 代码解析
1. 初始化地图
使用 new maplibregl.Map() 创建地图实例,配置基本参数。本示例使用D3.js加载远程GeoJSON数据。
2. 加载GeoJSON数据
使用D3.js的 d3.json() 方法加载远程徒步路线数据,保存完整坐标列表供后续动画使用。
3. 初始化动画
初始时只显示第一个坐标点,然后通过定时器逐步添加更多坐标。
4. 实时更新数据
使用 map.getSource('trace').setData(data) 方法实时更新数据源,实现轨迹动画效果。
5. 地图跟随
使用 map.panTo() 方法使地图跟随轨迹移动。
⚙️ 参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| container | string | 是 | 地图容器ID |
| style | string | 是 | 地图样式URL |
| zoom | number | 否 | 初始缩放级别,默认0 |
setData 方法
| 参数 | 类型 | 说明 |
|---|---|---|
| data | object | GeoJSON数据对象 |
🎨 效果说明

运行代码后:
- 地图初始显示全球视图(zoom: 0)
- 加载GeoJSON数据后,地图定位到徒步路线起点
- 黄色轨迹线(#ffff00)逐点绘制,形成动画效果
- 地图跟随轨迹移动,保持轨迹在视野中心
- 动画完成后自动停止
💡 常 见 问 题
Q1: 如何优化动画性能?
A: 可以使用 requestAnimationFrame 替代 setInterval,或降低更新频率。
Q2: 如何实现平滑的相机跟随?
A: 使用 map.easeTo() 替代 map.panTo() 实现平滑过渡。
Q3: 不使用D3.js如何加载数据?
A: 可以使用原生 fetch() API:
javascript
fetch(url)
.then(response => response.json())
.then(data => { /* 处理数据 */ });
📝 练习任务
- 基础练习:修改动画速度(setInterval的间隔时间)
- 进阶挑战:添加平滑相机跟随效果
- 拓展思考:如何实现轨迹颜色渐变?
🌟 最佳实践
- 性能优化 : 使用
requestAnimationFrame确保动画帧率稳定 - 数据管理 : 避免频繁创建新数据源,使用
setData更新 - 资源清理: 动画结束后清除定时器,避免内存泄漏
- 降级处理: 提供数据加载失败的fallback方案
🔗 延伸阅读
- Map API文档
- MapLibre GL JS 官方文档
- 下一课预告:将继续学习地图图层的基础知识
本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏