需求描述
需使用高德地图实现类似百度地图汽车模型路书的效果,即:
①在地图上添加一个沿着路径移动,且角度与路径一致的3D模型;
②3D模型移动过的路径用不同颜色显示出来;
在高德地图在线示例中实现的效果图(3D模型使用高德示例的小黄鸭):
参考代码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>3D模型轨迹回放</title>
<link rel="stylesheet" href="https://a.amap.com/jsapi_demos/static/demo-center/css/demo-center.css"/>
<style>
html, body, #container {
height: 100%;
width: 100%;
}
.input-card .btn {
margin-right: 1.2rem;
width: 9rem;
}
.input-card .btn:last-child {
margin-right: 0;
}
</style>
</head>
<body onLoad="mapInit()">
<div id="container"></div>
<div class="input-card">
<h4>轨迹回放控制</h4>
<div class="input-item">
<input type="button" class="btn" value="开始动画" id="start" onclick="startAnimation()"/>
<input type="button" class="btn" value="暂停动画" id="pause" onclick="pauseAnimation()"/>
</div>
<div class="input-item">
<input type="button" class="btn" value="继续动画" id="resume" onclick="resumeAnimation()"/>
<input type="button" class="btn" value="停止动画" id="stop" onclick="stopAnimation()"/>
</div>
</div>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&plugin=Map3D"></script>
<script>
var marker,
startPosition = new AMap.LngLat(116.478935, 39.997761),
lineArr = [[116.478935, 39.997761], [116.478939, 39.997825], [116.478912, 39.998549], [116.478912, 39.998549], [116.478998, 39.998555], [116.478998, 39.998555], [116.479282, 39.99856], [116.479658, 39.998528], [116.480151, 39.998453], [116.480784, 39.998302], [116.480784, 39.998302], [116.481149, 39.998184], [116.481573, 39.997997], [116.481863, 39.997846], [116.482072, 39.997718], [116.482362, 39.997718], [116.483633, 39.998935], [116.48367, 39.998968], [116.484648, 39.999861]];
var object3Dlayer, druckMeshes, gltfObj, oldDuck = null;
function mapInit() {
var map = new AMap.Map("container", {
viewMode: '3D',
resizeEnable: true,
center: startPosition,
zoom: 17
});
// 创建Object3DLayer图层
object3Dlayer = new AMap.Object3DLayer();
map.add(object3Dlayer);
// 引入3D模型加载插件
map.plugin(["AMap.GltfLoader"], function () {
gltfObj = new AMap.GltfLoader();
var angle = lineArr.length < 2 ? -90 : calcAngle(lineArr[0], lineArr[1]);
loadTheDuck(startPosition, angle);
});
// 创建覆盖物,用于实现轨迹回放
marker = new AMap.Marker({
map: map,
position: startPosition,
// icon: "https://webapi.amap.com/images/car.png",
content: "<div style='display:none'>隐藏</div>",
offset: new AMap.Pixel(-26, -13),
autoRotation: true,
angle: -90,
});
// 绘制原始路径轨迹
var polyline = new AMap.Polyline({
map: map,
path: lineArr,
showDir: true, // 显示方向箭头(地图为3D模式时无效)
strokeColor: "#28F", //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 8, //线宽
strokeStyle: "solid" //线样式
});
// 绘制行驶过的路径轨迹
var passedPolyline = new AMap.Polyline({
map: map,
// path: lineArr,
showDir: true, // 显示方向箭头(地图为3D模式时无效)
strokeColor: "#AF5", //线颜色
// strokeOpacity: 1, //线透明度
strokeWeight: 8, //线宽
// strokeStyle: "solid" //线样式
});
// 当覆盖物移动时,重绘行驶过的路径轨迹,重新加载3D模型
marker.on('moving', function (e) {
var passedPath = e.passedPath, lastPosi = passedPath[passedPath.length - 1];
passedPolyline.setPath(passedPath);
var angle = passedPath.length < 2 ? -90 : calcAngle(passedPath[passedPath.length - 2], lastPosi);
loadTheDuck(new AMap.LngLat(lastPosi.lng, lastPosi.lat), angle);
});
map.setFitView();
}
// 计算地图上两点间的角度
function calcAngle(start, end) {
var p_start = map.lngLatToContainer(start),
p_end = map.lngLatToContainer(end);
var diff_x = p_end.x - p_start.x,
diff_y = p_end.y - p_start.y;
return 360 * Math.atan2(diff_y, diff_x) / (2 * Math.PI);
}
// 在地图上添加3D模型
function loadTheDuck(position, angle) {
// 高德地图示例的小黄鸭
var urlDuck = 'https://a.amap.com/jsapi_demos/static/gltf/Duck.gltf';
var paramDuck = {
position: position, // 必须
scale: 180, // 非必须,默认1
height: 0, // 非必须,默认0
scene: 0, // 非必须,默认0
};
gltfObj.load(urlDuck, function (gltfDuck) {
druckMeshes = gltfDuck;
gltfDuck.setOption(paramDuck);
gltfDuck.rotateX(90);
gltfDuck.rotateY(0);
gltfDuck.rotateZ(angle);
if (oldDuck !== null) // 移除之前添加的模型
object3Dlayer.remove(oldDuck);
oldDuck = gltfDuck;
object3Dlayer.add(oldDuck);
});
}
// 开始动画,第一个参数为移动路径,第二个参数为移动速度
function startAnimation() {
marker.moveAlong(lineArr, 200);
}
function pauseAnimation() {
marker.pauseMove();
}
function resumeAnimation() {
marker.resumeMove();
}
function stopAnimation() {
marker.stopMove();
}
</script>
</body>
</html>
拷贝到这里运行看效果
参考文档
[1] 百度地图汽车模型路书
[2] 高德地图轨迹回放示例
[3] 高德地图glTF模型示例
[4] 高德地图glTF模型文档
[5] 高德地图AMap.Marker文档
[6] 高德地图计算两点间的角度