功能概述
出行轨迹功能允许用户在博客上展示自己的出行路线,以动画形式回放驾车轨迹。核心特性包括:
- 粘贴高德地图导航分享链接,一键导入起终点
- 前台自动调用高德驾车路径规划 API,生成真实路线
- 小汽车图标沿路线动画回放,支持速度调节
- 地图跟随/自由模式切换,回放中可拖拽地图
- 后台仅需管理起终点信息,路线数据由前台自动获取
整体架构
1┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
2│ 高德地图APP │────▶│ 后台管理 │────▶│ amap.toml 数据 │
3│ 分享导航链接 │ │ 轨迹管理页面 │ │ (起终点+坐标) │
4└─────────────┘ └──────────────┘ └────────┬────────┘
5 │ Hugo 构建
6 ▼
7 ┌─────────────────┐
8 │ 前台轨迹回放页面 │
9 │ single.html │
10 │ AMap JS API 2.0 │
11 └─────────────────┘
数据流非常简洁:后台只存储起终点名称和坐标,前台根据这些信息自动规划路线并回放。
后台实现
数据结构
后台使用 TOML 格式存储轨迹数据,每条轨迹只保留最核心的字段:
1[[trip]]
2 name = "临沂新疆五日游"
3 date = "2026-05-20"
4 startName = "双月湖"
5 endName = "乌鲁木齐"
6 startLng = 118.345
7 startLat = 35.012
8 endLng = 87.617
9 endLat = 43.793
不存储路径坐标、里程、耗时等数据——这些全部由前台通过高德 API 实时获取。
导入解析
支持三种高德地图分享链接格式:
高德 APP 分享链接:
uri.amap.com/navigation?from=lng,lat,name&to=lng,lat,name- 前端直接解析 URL 参数,提取起终点坐标和名称
高德短链接:
surl.amap.com/xxx- 后端代理解析:HTTP 请求短链接 → 跟随重定向 → 解析目标 URL 参数
高德网页版导航:
ditu.amap.com/dir?from=lng,lat&fromname=xxx- 前端直接解析 URL 参数
拖拽排序
使用 HTML5 原生 Drag & Drop API 实现卡片拖拽排序,无需引入第三方库:
1// 拖拽开始
2onDragStart(idx, e) { dragIdx = idx; e.dataTransfer.effectAllowed = 'move' }
3
4// 放置时交换位置
5onDrop(idx) {
6 const item = trips.splice(dragIdx, 1)[0]
7 trips.splice(idx, 0, item)
8}
拖拽时源卡片半透明,目标卡片高亮边框,提供清晰的视觉反馈。
前台实现
地图初始化
使用高德地图 JS API 2.0,按需加载插件:
1// 安全密钥(必须在加载 API 之前设置)
2window._AMapSecurityConfig = { securityJsCode: "你的安全密钥" };
3
4// 加载 API
5<script src="https://webapi.amap.com/maps?v=2.0&key=你的Key"></script>
6
7// 按需加载动画插件
8AMap.plugin('AMap.MoveAnimation', function() { /* 初始化地图 */ });
驾车路径规划
当轨迹只有起终点坐标(无详细路径)时,前台自动调用 AMap.Driving 进行路径规划:
1AMap.plugin('AMap.Driving', function() {
2 var driving = new AMap.Driving({ policy: 0 }); // 最快路线
3 driving.search(
4 new AMap.LngLat(startLng, startLat),
5 new AMap.LngLat(endLng, endLat),
6 function(status, result) {
7 if (status === 'complete') {
8 // 提取路径坐标
9 var fullPath = extractPath(result.routes[0]);
10 // 提取途经道路
11 var roads = extractRoads(result.routes[0]);
12 // 更新里程、耗时、均速
13 updateTripData(result.routes[0]);
14 }
15 }
16 );
17});
规划成功后自动获取:
- 完整路径坐标(用于绘制轨迹线和小车移动)
- 里程、耗时、均速
- 途经道路名称列表
轨迹回放动画
参照高德官方示例,使用 marker.moveAlong 实现小车沿轨迹移动:
1// 创建小汽车标记
2var marker = new AMap.Marker({
3 map: map,
4 position: path[0],
5 icon: 'car.png',
6 offset: new AMap.Pixel(-13, -26),
7});
8
9// 绘制轨迹线
10var polyline = new AMap.Polyline({
11 map: map,
12 path: path,
13 showDir: true,
14 strokeColor: '#28F',
15 strokeWeight: 6,
16});
17
18// 已经过的路径(绿色)
19var passedPolyline = new AMap.Polyline({
20 map: map,
21 strokeColor: '#AF5',
22 strokeWeight: 6,
23});
24
25// 小车移动时更新已过路径
26marker.on('moving', function(e) {
27 passedPolyline.setPath(e.passedPath);
28 if (followMode) map.setCenter(e.target.getPosition(), true);
29});
30
31// 开始回放
32marker.moveAlong(path, {
33 duration: baseDuration / speedMultiplier,
34 autoRotation: true,
35});
速度控制
提供 1x-50x 速度滑块,默认 10x。速度公式:
1var baseDuration = Math.max(100, Math.min(500, Math.round(10000 / path.length)));
2var segDuration = Math.max(20, Math.round(baseDuration / speedMultiplier));
每段路径的基础时长根据路径点数自适应,再除以速度倍率,最低 20ms 保证流畅。
地图交互
回放中地图默认跟随小车,但用户拖拽地图时自动切换为自由模式:
1map.on('dragstart', function() {
2 if (animating && followMode) {
3 followMode = false;
4 // 更新按钮状态为"自由"
5 }
6});
也可通过「跟随/自由」按钮手动切换。暂停回放时地图完全自由操作。
错误处理
- API 加载失败:检测
AMap是否存在,显示域名白名单配置提示 - 路径规划超时:8 秒超时保护,降级为直线连接
- 路径规划失败:显示具体失败原因
本地开发注意事项
高德地图 API Key 有域名白名单限制,localhost 不符合规范。本地开发时需使用 127.0.0.1:1313 访问,并在高德控制台将 127.0.0.1 添加到 Key 白名单。
技术要点总结
| 模块 | 技术方案 |
|---|---|
| 地图渲染 | 高德 JS API 2.0 + AMap.MoveAnimation |
| 路径规划 | AMap.Driving 前端实时规划 |
| 数据存储 | TOML 格式,仅起终点坐标 |
| 链接解析 | 前端 URL 解析 + 后端短链接代理 |
| 回放动画 | marker.moveAlong + passedPolyline |
| 速度控制 | 段时长 / 速度倍率,1x-50x |
| 地图交互 | dragstart 自动切换自由模式 |
| 拖拽排序 | HTML5 Drag & Drop API |
| 错误处理 | API 加载检测 + 超时保护 + 降级方案 |
留言评论
期待你的想法评论加载中