轨迹回放

根据业务场景结合vue+iview在百度lushu的prototype中新增一些回调属性如:_pauseCallback、_endCallback、_sliderPos进行回放进度、回放速度的控制
涉及到的交互及限制:vue

  1. 回放进度(暂停时拖动,播放中没法控制)
  2. 回放速度(移动中须要到下一个坐标点,若距离太长两点之间没法变动速度)

图片描述
tip:算法

  • 测试数据中相邻坐标点的间隔不匀会致使进度条的快慢不等
  • 进度条位置_sliderPos的算法不太精确须要再作优化可自行修改

代码

<template>
    <div>
        <div id="allmap"></div>
        <div class="slideBar track">
            <Row type="flex" justify="center" align="middle">
                <Col span='6'>回放进度</Col>
                <Col span='15'>
                    <Slider v-model="progressVal" :disabled='sliderStatus' @on-input='progressChange'></Slider>
                </Col>
            </Row>
            <Row type="flex" justify="center" align="middle">
                <Col span='6'>回放速度</Col>
                <Col span='15'>
                    <Slider v-model="speedVal" :min='1' :max='10' :disabled='sliderStatus' @on-input='speedChange'></Slider>
                </Col>
            </Row>
            <Row type="flex" justify="center">
                <Col span='10'>
                    <Button  class='btn' size="large" @click='pause' :disabled='pauseStatus'>暂停</Button>
                </Col>
                <Col span='8'>
                    <Button type='primary' size="large" @click='run' :disabled='playStatus'>播放</Button>
                </Col>
            </Row>
        </div>
    </div>
</template>
<script>
export default {
    methods:{
        init(){
             this.map = new BMap.Map('allmap',{enableMapClick:false});
             this.map.enableScrollWheelZoom(true)
             this.map.centerAndZoom('杭州', 12);
             this.iconStart = new BMap.Icon(mobike, new BMap.Size(36,39),{anchor : new BMap.Size(18, 39)});
             BMapLib.LuShu.prototype._addMarker=function(callback) {
                if (this._marker) {
                    this.stop();
                    this._map.removeOverlay(this._marker);
                    clearTimeout(this._timeoutFlag);
                }
                //移除以前的overlay
                this._overlay && this._map.removeOverlay(this._overlay);
                var marker = new BMap.Marker(this._path[0].point);
                this._opts.icon && marker.setIcon(this._opts.icon);
                this._map.addOverlay(marker);
                this._marker = marker;
                
            }
            BMapLib.LuShu.prototype._setLabel=(me,pointInfo)=>{
                 me._map.removeOverlay(me._marker.getLabel());
                 me._marker.setLabel(new BMap.Label(this.getContentTemplate(pointInfo,false),{offset:new BMap.Size(40,-10)}))
            }
            BMapLib.LuShu.prototype._move=function(initPos,targetPos,effect,initPosInfo,targetPosInfo) {
                var pointsArr=[initPos,targetPos];  //点数组
                var me = this,
                    //当前的帧数
                    currentCount = 0,
                    //步长,米/秒
                    timer = 10,
                    step = this._opts.speed / (1000 / timer),
                    //初始坐标
                    init_pos = this._projection.lngLatToPoint(initPos),
                    //获取结束点的(x,y)坐标
                    target_pos = this._projection.lngLatToPoint(targetPos),
                    //总的步长
                    count = Math.round(me._getDistance(init_pos, target_pos) / step);
                 
                //若是小于1直接移动到下一点
                if (count < 1) {
                    me._moveNext(++me.i);
                    return;
                }
                me._intervalFlag = setInterval(function() {
                //两点之间当前帧数大于总帧数的时候,则说明已经完成移动
                    if (currentCount >= count) {
                        me._endCallback(initPosInfo,targetPosInfo)
                        clearInterval(me._intervalFlag);
                        //移动的点已经超过总的长度
                        if(me.i > me._path.length){
                            return;
                        }
                        //运行下一个点
                        me._moveNext(++me.i);
                    }else {
                            currentCount++;
                            var x = effect(init_pos.x, target_pos.x, currentCount, count),
                                y = effect(init_pos.y, target_pos.y, currentCount, count),
                                pos = me._projection.pointToLngLat(new BMap.Pixel(x, y));
                            //设置marker
                            if(currentCount == 1){
                                var proPos = null;
                                if(me.i - 1 >= 0){
                                    proPos = me._path[me.i - 1].point;
                                }
                                if(me._opts.enableRotation == true){
                                     me.setRotation(proPos,initPos,targetPos);
                                }
                                if(me._opts.autoView){
                                    if(!me._map.getBounds().containsPoint(pos)){
                                        me._map.setCenter(pos);
                                    }  
                                }
                            }
                            //设置label
                            me._setLabel(me,initPosInfo)
                            //正在移动
                            me._marker.setPosition(pos,initPos);
                            //设置自定义overlay的位置
                            me._setInfoWin(pos);  
                            me._sliderPos(initPos,targetPos,initPosInfo,targetPosInfo)
                        }
                },timer);
            };
            BMapLib.LuShu.prototype._moveNext= function(index) {
                var me = this;
                if (index < this._path.length - 1) {
                    me._move(me._path[index].point, me._path[index + 1].point, me._tween.linear,me._path[index],me._path[index+1]);
                }
            },
            BMapLib.LuShu.prototype.pause = function() {
                clearInterval(this._intervalFlag);
                //标识是不是按过pause按钮
                this._fromPause = true;
                this._clearTimeout();
                this._pauseCallback()
            };
            BMapLib.LuShu.prototype._sliderPos=(initPos,targetPos,initPosInfo)=>{
                this.currentPoint = this.pointList.map((item)=>{ return item.locationTime}).indexOf(initPosInfo.locationTime)
                this.progressVal =  Number(((this.currentPoint/this.pointList.length)*100).toFixed(0))
                this.handler = false
            };
            BMapLib.LuShu.prototype._endCallback=(initPosInfo,targetPosInfo)=>{
                if (targetPosInfo.locationTime==this.pointList.slice().pop().locationTime) {
                    this.progressVal=100
                    this.handler = true
                    this.playStatus = false
                    this.pauseStatus =true
                    this.$Message.success('播放完成')
                }
            };
            BMapLib.LuShu.prototype._pauseCallback=()=>{
                this.handler  =true
            };
            BMapLib.LuShu.prototype.removeOverlay=function(){
                this._map.removeOverlay(this._marker)
            }
        
        },
        run(){
            if (this.progressVal==100) {
                this.restart = true
                this.$Message.info({
                    top: 50,
                    duration: 3,
                    render: h => {
                        return h('span', [
                            '播放已完成,是否',
                            h('a', {
                                on:{
                                    'click':()=>{
                                        if (this.restart) {
                                            this.progressVal = 0;
                                            this.restart = false
                                            setTimeout(()=>{
                                                this.pauseStatus = false
                                                this.run()
                                            },400)
                                        }
                                    }
                                }
                            },'从新播放'),'?'
                        ])
                    }
                });
                return
            }else{
                this.pauseStatus = false
                this.playStatus = true
                this.start.hide()
            }
            if (this.type==='pause') {
                this.lushu.start()
                return
            }
            //this.map.clearOverlays(); 
            //this.map.addOverlay(this.polyline);
            this.lushu = new BMapLib.LuShu(this.map,this.pointList.slice(this.cut),{
                //defaultContent:"粤A30780",//"从天安门到百度大厦"
                autoView:false,//是否开启自动视野调整,若是开启那么路书在运动过程当中会根据视野自动调整
                icon  : this.iconStart,
                speed: this.speed,
                enableRotation:false,//是否设置marker随着道路的走向进行旋转
                landmarkPois:[]
                    
            }); 
            this.lushu.start()
        },
        pause(){
            this.playStatus = false
            this.type = 'pause'
            this.lushu.pause()
        },
        speedChange(val){
            this.lushu._opts.speed = val*30
            this.speed=val*30
        },
    }
}
</script>
百度lushu源码参考 http://api.map.baidu.com/libr...
相关文章
相关标签/搜索