基于百度路书js实现车辆轨迹回放功能:接到一个新需求,实现车辆历史轨迹回放功能,之前没有做过,根据网上各种文章走了一些坑,基本上都是半成品,最后还是看百度地图原生api完成开发,现在把最终结果分享给大家。


文章目录

  • 前言
  • 一、车辆轨迹回放实现前提是什么?
  • 二、为什么用百度路书功能?
  • 二、直接上代码
  • 1.效果图
  • 2.代码
  • 总结



前言

项目技术选型:我们这里是springboot项目,前端框架是bootstrap,页面采用html,所以采用javascript地图解决方案,之前有百度地图做过可视化,所以选择百度地图+javascript+路书实现。


一、车辆轨迹回放实现前提是什么?

前提:必须有可连续描点成轨迹线路的经纬度数据,我们已有gps硬件三方api可以获取指定时间段内的车辆gps定位经纬度数据,json格式,这个是前提。还有注意经纬度格式和地图匹配,我这里使用百度地图,经纬度格式符合百度地图描点要求。开发前先要在百度地图申请开发者AK,具体方法百度一下即可。

二、为什么用百度路书功能?

说明:首先注意js引入的百度地图版本,不同的版本关于map操作语法不一样,早期没有路书,车辆轨迹回放是通过图层遮盖实现的,比较麻烦,后期版本加入了路书功能,实现更加简单,这里使用新版本BMapGL。
注意:BMapGL和BMap不一样,跟引入的百度地图版本有关。

<script type="text/javascript"
        src="http://api.map.baidu.com/api?type=webgl&v=1.0&ak=你的ak"></script>
    <script type="text/javascript" src="http://bj.bcebos.com/v1/mapopen/github/BMapGLLib/Lushu/src/Lushu.min.js"></script>

二、直接上代码

1.效果图

路书匹配骑行路线适合FLink处理吗 路书怎么使用_javascript


两种效果,一种普通地图,一种卫星地图,区别只有几行代码,普通地图注释掉就可以了。

路书匹配骑行路线适合FLink处理吗 路书怎么使用_百度地图_02


点击左下角按钮,可以控制汽车动画开始、停止、暂停等操作。

2.代码

代码如下(示例):

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <title>路书</title>
    <style type="text/css">
        body,
        html {
            width: 100%;
            height: 100%;
            margin: 0;
            font-family: "微软雅黑";
        }
        ul li {list-style: none;}
        #map_canvas {
            width: 100%;
            height: 100%;
        }

        #result {
            width: 100%
        }
        #btns {
            z-index: 999;
            position: fixed;
            bottom: 3.5rem;
            margin-left: 2.5rem;
            padding-left: 0;
            border-radius: .25rem;
            display: flex;
            box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5);
            text-align:center;
        }
        #btns li{
            border-right: 1px solid #d2d2d2;
            padding:10px 10px;
            height: 100%;
            background-color: #fff;
            cursor: pointer;
            color:#3a79b5;
        }
    </style>
    <script>
        window.BMAP_AUTHENTIC_KEY = '7Cc5Kmn672miPzG4qQhvlOrERcXMMinq';
    </script>
    <!-- JavaScript Plugins -->
	<script type='text/javascript' src='/js/utils/jquery-1.7.2.min.js' ></script>
	<script type='text/javascript' src='/js/utils/jquery.mousewheel.min.js' ></script>
	<script type='text/javascript' src='/js/utils/jquery.placeholder.js' ></script>
	<script type='text/javascript' src='/js/utils/jquery.fileinput.js' ></script>
	<script type='text/javascript' src='/js/utils/jquery.form.js' ></script>
    <script type="text/javascript"
        src="http://api.map.baidu.com/api?type=webgl&v=1.0&ak=你的ak"></script>
    <script type="text/javascript" src="http://bj.bcebos.com/v1/mapopen/github/BMapGLLib/Lushu/src/Lushu.min.js"></script>
    <style>
       html,body,#container {
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            padding: 0
        }
        .info {
            z-index: 999;
            width: auto;
            padding: 10px;
            margin-left: 10px;
            position: fixed;
            top: 10px;
            background-color: #fff;
            border-radius: 5px;
            font-size: 14px;
            color: #666;
            box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5);
        }
        ul li {
            list-style: none;
        }
        .btn-wrap {
            z-index: 999;
            position: fixed;
            bottom: 30px;
            left: 10px;
            padding: 10px;
            border-radius: 5px;
            background-color: #fff;
            box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5);
        }
        .btn {
            width: 100px;
            height: 30px;
            float: left;
            background-color:rgba(265, 265, 265, 0.9);
            color: rgba(27, 142, 236, 1);
            font-size: 14px;
            border:1px solid rgba(27, 142, 236, 1);
            border-radius: 5px;
            margin: 0 5px;
            text-align: center;
            line-height: 30px;
        }
        .btn:hover {
            background-color: rgba(27, 142, 236, 0.8);
            color: #fff;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div id="map_canvas"></div>
    <div id="result"></div>
    <ul id='btns'>
        <li id="run">开始</li>
        <li id="stop">停止</li>
        <li id="pause">暂停</li>
        <li id="hide">隐藏信息窗口</li>
        <li id="show">展示信息窗口</li>
        <li id="showRoadNet">显示路网</li>//不需要卫星地图的注释掉
        <li id="hideRoadNet">隐藏路网</li>//不需要卫星地图的注释掉
    </ul>
    <script type="text/javascript">
    
	  	//获取历史轨迹数据,后台获取经纬度api接口
		window.onload = function(){
		    //查询基础数据
		    $.ajax({
		    	type:'get',
				async:false,
				dataType:"json",
		        url : "后台获取经纬度api接口",
		        success : function(data) {
		        	setTrackmap(data.aaData,data.carNum)
		        }
		    });
		}
	  	
		function setTrackmap(arrPois,carNum) {
			
			if(arrPois!=null && arrPois!=false){
		        var map = new BMapGL.Map('map_canvas');
		      	//控件
		        map.addControl(new BMapGL.ZoomControl());// 添加缩放控件
		        map.enableScrollWheelZoom();
		        map.setMapType(BMAP_EARTH_MAP);      // 设置地图类型为地球模式,不需要卫星地图的注释掉
		       // map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 13);
		        map.setTilt(73);//不需要卫星地图的注释掉
		
		       //开始位置 结束位置 开始时间,结束时间
            	var startPoint,endPoint;
            	var arrPoisT = [];//点位信息
		       
		      	//经纬度点位整理
	            for (let i = 0 && arrPois.length>0; i < arrPois.length; i++) {
	           	 
	                var point = new BMapGL.Point(arrPois[i].toString().split(',')[0],arrPois[i].toString().split(',')[1]); 
	                 //业务逻辑
	                if(i===0){
	                  //开始位置
	                  startPoint = point
	                }
	                 
	                 //结束位置
	                endPoint=point
	                arrPoisT.push(point);
	              }
            	
	            map.centerAndZoom(arrPoisT[0], 12);
	            
		        var lushu;
		        var marker;
		        
		        var markerStart = new BMapGL.Marker(startPoint);  // 创建标注
	            var markerEnd = new BMapGL.Marker(endPoint);  // 创建标注
	            
	            //添加开始结束点            
	            //map.addOverlay(markerStart);
	            map.addOverlay(markerEnd);
	            markerEnd.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
	          	//以下是地图上的标注信息
	            //markerStart.setLabel(setLabelStyle("起点"));
	            //markerEnd.setLabel(setLabelStyle("终点"));
	            
	            marker=new BMapGL.Marker(startPoint,{
	                //引入小车图标
	                icon  : new BMapGL.Icon('/commonPic/car.png', new BMapGL.Size(52,26),{anchor : new BMapGL.Size(27, 13)})
	            });
	            
	          	//展示时小车样式
	            var label = new BMapGL.Label(carNum,{offset:new BMapGL.Size(-33,-45)});
	            label.setStyle({textAlign: 'center',border:"white .5px solid",color: "white",borderRadius:"2px",boxShadow:'0 0 1px 2px #1e68bb',padding:"2px 9px",background:"#1e68bb",});
	            marker.setLabel(label);

	            map.addOverlay(marker);
	            
	            
		        // 实例化一个驾车导航用来生成路线
		        var drv = new BMapGL.DrivingRoute('地区', {
		            onSearchComplete: function (res) {
		                if (drv.getStatus() == BMAP_STATUS_SUCCESS) {
		                    var plan = res.getPlan(0);
		                   /*  var arrPois = [];
		                    for (var j = 0; j < plan.getNumRoutes(); j++) {
		                        var route = plan.getRoute(j);
		                        arrPois = arrPois.concat(route.getPath());
		                    } */
		                    map.addOverlay(new BMapGL.Polyline(arrPoisT, {
		                    	strokeColor : "red",
		                        strokeWeight : 5,//宽度
		                        strokeOpacity : 1//透明度
		                    }));
		                    map.setViewport(arrPoisT);
		
		                    lushu = new BMapGLLib.LuShu(map, arrPoisT, {
		                        defaultContent: carNum, // "信息窗口文案"
		                        autoView: true, // 是否开启自动视野调整,如果开启那么路书在运动过程中会根据视野自动调整
		                        speed: 500,
		                        // icon: new BMapGL.Icon('./images/car.png', new BMapGL.Size(32, 32), { anchor: new BMapGL.Size(10, 10) }),
		                        icon: new BMapGL.Icon('/commonPic/car.png', new BMapGL.Size(52,26),{anchor : new BMapGL.Size(27, 13)}),
		                        enableRotation: true, // 是否设置marker随着道路的走向进行旋转
		                    });
		                }
		            }
		        });
		        

	            //点击小车开始监听事件
	            marker.addEventListener("click",function(){
	                marker.enableMassClear();   //设置后可以隐藏改点的覆盖物
	                marker.hide();
	                lushu.start();
	                //map.clearOverlays();  //清除所有覆盖物
	            });
	            
		        drv.search(startPoint, endPoint);
		
		        //绑定事件
		        $("run").onclick = function () {
		        	 marker.enableMassClear();   //设置后可以隐藏改点的覆盖物
		             marker.hide();
		        	 
		            //开始
		            lushu.start();
		        }
		        $("stop").onclick = function () {
		            //停止
		            lushu.stop();
		        }
		        $("pause").onclick = function () {
		            //暂停
		            lushu.pause();
		        }
		        $("hide").onclick = function () {
		            //隐藏信息窗口
		            lushu.hideInfoWindow();
		        }
		        $("show").onclick = function () {
		            //展示信息窗口
		            lushu.showInfoWindow();
		        }
		        $("showRoadNet").onclick = function () {
		            map.setDisplayOptions({
		                street: true,     //是否显示路网(只对卫星图和地球模式有效),不需要卫星地图的注释掉
		            })
		        }
		        $("hideRoadNet").onclick = function () {
		            map.setDisplayOptions({
		                street: false,     //是否显示路网(只对卫星图和地球模式有效),不需要卫星地图的注释掉
		            })
		        }
		        function $(element) {
		            return document.getElementById(element);
		        }
			}else{
				var map = new BMapGL.Map('map_canvas');
		        map.enableScrollWheelZoom();
		        map.setMapType(BMAP_EARTH_MAP);      // 设置地图类型为地球模式
		       // map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 13);
	          	
		       //控件
		        map.addControl(new BMapGL.ZoomControl());// 添加缩放控件
		        var startPoint = new BMapGL.Point(116.643367,41.217292);
	            map.centerAndZoom(startPoint, 11);
	            
		        var lushu;
		        var marker;
		        
		        var markerStart = new BMapGL.Marker(startPoint);  // 创建标注
	            //var markerEnd = new BMapGL.Marker(endPoint);  // 创建标注
	            
	            //添加开始结束点            
	            //map.addOverlay(markerStart);
	            //map.addOverlay(markerEnd);
	            //markerEnd.setAnimation(BMAP_ANIMATION_BOUNCE); //跳动的动画
	          	//以下是地图上的标注信息
	            //markerStart.setLabel(setLabelStyle("起点"));
	            //markerEnd.setLabel(setLabelStyle("终点"));
	            
	            marker=new BMapGL.Marker(startPoint,{
	                //引入小车图标
	                icon  : new BMapGL.Icon('/commonPic/car.png', new BMapGL.Size(52,26),{anchor : new BMapGL.Size(27, 13)})
	            });
	            
	          	//展示时小车样式
	            var label = new BMapGL.Label("车辆无信号",{offset:new BMapGL.Size(-33,-45)});
	            label.setStyle({textAlign: 'center',border:"white .5px solid",color: "white",borderRadius:"2px",boxShadow:'0 0 1px 2px #1e68bb',padding:"2px 9px",background:"#1e68bb",});
	            marker.setLabel(label);

	            map.addOverlay(marker);
	            
	            //绑定事件
		        $("run").onclick = function () {
		        	 marker.enableMassClear();   //设置后可以隐藏改点的覆盖物
		             marker.hide();
		        	 
		            //开始
		            lushu.start();
		        }
		        $("stop").onclick = function () {
		            //停止
		            lushu.stop();
		        }
		        $("pause").onclick = function () {
		            //暂停
		            lushu.pause();
		        }
		        $("hide").onclick = function () {
		            //隐藏信息窗口
		            lushu.hideInfoWindow();
		        }
		        $("show").onclick = function () {
		            //展示信息窗口
		            lushu.showInfoWindow();
		        }
		        function $(element) {
		            return document.getElementById(element);
		        }
			}
		}
    </script>
</body>

</html>

总结

百度路书其实也是封装了原有图层遮盖描点的方法,只是更加简单方便,开箱即用,比较适合我这种后台开发。