百度地图API开发轨迹回放功能

用百度地图开放平台提供的功能做一个轨迹回放,包括暂停、倍速播放、重点点位标注,而且轨迹是逐渐出现,而非一段一段画出来的。
网上有轨迹回放的文章,大多是用线覆盖物一段一段的画,达不到逐渐出现的效果。而百度地图自己提供的new
BMapGLLib.TrackAnimation方法,好像无法实现倍速,调整了duration也无法实时的渲染进去,还有就是无法在到达某个点的时候做判断是否添加特殊标注。我看了TrackAnimation的api,可能通过addPath和setDuration可以实现,但是我没有成功。
我最后采用的是把TrackAnimation和setTimeout结合起来,一段一段的渲染,最终达到了我想要的效果。

首先我用到了这些变量。
		var bPoints=[];      //所有点 mapPoint
    var timerTask;     //timeOut任务
    var velocity = 1;    //播放倍速
    var trackAni; //轨迹事件
    var targetTime;//timeOut任务执行的时间点
    var remainTime;//暂停使用
    var newindex;//最新点的索引
    var varList;//数据库提取过来的点位的原始数据
下面这个方法从数据库提取数据,并标注起点,开始做轨迹动画
function loadTrackByTime() {
    //初始化各项数据
    $("#pauseBtn").html('暂停');//暂停播放按钮文字控制
    if(trackAni){
        trackAni.cancel();//点击回放销毁之前的动画
    }
    map.clearOverlays();
    bPoints=[];
    clearTimeout(timerTask);
    //获取起止时间
    var daterange = $("#select1").val().split("~");
    var ADDTIMES = daterange[0];
    var ADDTIMEE = daterange[1].replace(' ','');
    $.ajax({
        xhrFields: {
            withCredentials: true
        },
        url: httpurl,
        type: 'POST',
        data: {ADDTIMES:ADDTIMES,ADDTIMEE:ADDTIMEE,tm:new Date().getTime()},
        success: function (data) {
            if("success" == data.result){
                var path = [];
                if(data.workerSite && data.workerSite.length > 0){
                    varList = data.workerSite;
                        $.each(data.workerSite,function (index, item) {
                        bPoints.push(new BMapGL.Point(item.W_LNG,item.W_LAT));
                    });
                    //添加起点标志
                    var markerS = new BMapGL.Marker(bPoints[0]);
                    var labelS = new BMapGL.Label('起点',{offset:new BMapGL.Size(-15,2)});
                    labelS.setStyle({
                        background:'white',color:'black',border:'1px solid',fontSize:'15px',
                    });
                    markerS.setLabel(labelS);
                    map.addOverlay(markerS);
                    //开始画轨迹
                    if(bPoints.length>1){
                        newindex = 1;
                        timeOutStart();
                    }
                }
            }
        }
    })
}

下面这个方法用来控制动画

function timeOutStart(){
        if(newindex < bPoints.length){
            //如果滞留,加一个标记,进入下一段
            if(varList[newindex].IS_RETENTION == '是'){
                var markerR = new BMapGL.Marker(bPoints[newindex]);
                var labelR = new BMapGL.Label('滞留',{offset:new BMapGL.Size(-15,2)});
                labelR.setStyle({
                    background:'white',color:'black',border:'1px solid',fontSize:'15px',
                });
                markerR.setLabel(labelR);
                map.addOverlay(markerR);
                newindex++;
                setTimeout(function () {
                    timeOutStart();
                },300/velocity);

            }else{
                var thisIntervla = 10000/velocity;
                var tempPoints = [];
                tempPoints.push(bPoints[newindex-1]);
                tempPoints.push(bPoints[newindex]);
                var pl = new BMapGL.Polyline(tempPoints);
                trackAni = new BMapGLLib.TrackAnimation(map, pl, {
                    overallView: newindex === bPoints.length-1,
                    tilt: 80,
                    duration: thisIntervla,
                    delay: 0
                });
                trackAni.start();
                newindex++;
                if(newindex === bPoints.length-1){
                    //添加终点标志
                    var markerE = new BMapGL.Marker(bPoints[bPoints.length-1]);
                    var labelE = new BMapGL.Label('终点',{offset:new BMapGL.Size(-15,2)});
                    labelE.setStyle({
                        background:'white',color:'black',border:'1px solid',fontSize:'15px',
                    });
                    markerE.setLabel(labelE);
                    map.addOverlay(markerE);
                }
                timerTask = setTimeout(function () {
                    if(newindex < bPoints.length){
                        timeOutStart(newindex);
                    }
                },thisIntervla+50)
                targetTime = new Date().getTime()+thisIntervla+50;
            }
        }
    }

下面这个方法是暂停、继续播放的方法

function pauseAni () {
        if($("#pauseBtn").html() == '播放'){
            trackAni.continue();
            $("#pauseBtn").html('暂停');
            if(remainTime){
                timerTask = setTimeout(function () {
                    if(newindex < bPoints.length){
                        timeOutStart(newindex);
                    }
                },remainTime)
                targetTime = new Date().getTime()+remainTime;
            }
        }else if($("#pauseBtn").html() == '暂停'){
            trackAni.pause();
            clearTimeout(timerTask);
            remainTime = targetTime - new Date().getTime();
            console.log('remainTime:'+remainTime);
            console.log('now:'+new Date().getTime());
            $("#pauseBtn").html('播放');
        }
    }
    最后是控制播放倍速的方法
     function setV(level) {
        velocity = level;
    }

我借鉴了网上的很多篇文章,最后结合项目自己做出来的方法。其中的难点在于如何衔接动画,也就是如何让一个setTimeOut接上另一个setTimeOut,关键是要可以暂停。所以targetTime的使用比较重要,不能出错。

这个方法最终有一个瑕疵,倍速播放不能立即生效,必须再下一段开始时生效。但是我们的项目最多一分钟就会有一个位置点传过来,每天都有几百个点位,所以几乎不会察觉。

  • 1
    点赞
  • 5
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

chedanquestion

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值