百度地图路书边走边画功能

百度地图官方提供的BMapGL,不能直接实现边走边画的功能,自带api也没有此功能。所以从网上找了许多案例,然后结合了自己的一些理解整合出了下面的基本功能。

​ 需求: 从后台获得坐标点阵,画出轨迹图,小车动画跟随画线,边走边画。附加速度调整功能和暂停开始功能。

​ 分析: 原生js不能实现边走边画,所以我们要自己来画线,画线具体操作见下方

首先要引入

<!-- 百度地图 -->
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=自己的"></script>
<!-- 路书 -->
<script type="text/javascript" src="http://api.map.baidu.com/library/LuShu/1.2/src/LuShu_min.js"></script>

然后是页面部分,这里是通过弹窗来新增一个路书地图,需要引入elementUI

<!-- 弹窗 -->
<el-dialog
    title="轨迹回放"
    :visible.sync="dialogVisible"
    width="1200px"
    :before-close="cancel">
    <div class="win-cont">
        <!-- 时间 -->
        <!-- 这个部分是通过时间段从后台获取坐标点集合的查询框 -->
        <el-form class="form-cont">
            <el-form-item label="时间选择">
                <el-date-picker
                    v-model="startEndTime"
                    type="datetimerange"
                    range-separator="至"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期">
                </el-date-picker>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="submitPlay" size="medium">查询</el-button>
            </el-form-item>
        </el-form>
        <!-- 播放按钮 -->
        <div class="play-cont" @click="playMap">
            <svg-icon v-if="!play" icon-class="play" class-name="card-panel-play" />
            <svg-icon v-else icon-class="close_1" class-name="card-panel-play" />
        </div>
        <!-- 速度控制 -->
        <!-- 这里用的是elementui选择器,用法可看官网 -->
        <div class="speed-select">
          <el-select v-model="speed" placeholder="速度变更">
            <el-option
              v-for="item in options"
              :key="item.speed"
              :label="item.label"
              :value="item.speed"
              @change="speedChange"
              size="mini">
            </el-option>
          </el-select>
        </div>
        <div :id="id" class="map1" style="height:520px; width: 100%"></div>
    </div>
</el-dialog>

下面是功能部分

创建(路书)地图

createPolyMap (data, row) {
    console.log(data, row, this.id)
    let bmap = new BMap.Map(this.id)      // 创建Map实例
    bmap.centerAndZoom(new BMap.Point(row.lat, row.lng), 19)    // 初始化地图,设置中心点坐标和地图级别19
    bmap.enableScrollWheelZoom(true)    //设置地图可通过鼠标滚轮缩放
    bmap.setMapType(BMAP_HYBRID_MAP);    //设置地图类型为混合型
    this.bmap = bmap
    // 清除轨迹缓存
    this.bmap.clearOverlays()
    //创建轨迹
    this.createPolyLine(data, bmap)
}

创建轨迹和画线逻辑

createPolyLine (data, bmap) {
    let points = []
    if (!data.length) return
    data.forEach(e => {
        points.push(new BMap.Point(e.lat, e.lng))
    })
    let icon = 'http://developer.baidu.com/map/jsdemo/img/car.png'
    let marker=new BMap.Marker(points[0],{
      //引入小车图标,前面一个size参数是图标大小,后面一个size是中心点位置,一般一半就行
      icon : new BMap.Icon(icon, new BMap.Size(44,44),{anchor : new BMap.Size(22, 22)})
    })
    //展示时小车样式
    let label = new BMap.Label('',{offset:new BMap.Size(0,-30)});
    label.setStyle({border:"2px red rgb(204, 204, 204)",color: "rgb(2, 0, 0)",borderRadius:"10px",padding:"5px",background:"rgb(222, 255, 255)",});
    marker.setLabel(label);
    bmap.addOverlay(marker);
    //设置路书动画
    BMapLib.LuShu.prototype._move=function(initPos,targetPos,effect) {
      let pointsArr=[initPos,targetPos];  //点数组
      let me = this,
      //当前的帧数
      currentCount = 0,
      //步长,米/秒
      timer = 5,
      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);
    //显示折线 syj201607191107

    // 画线操作
    this._map.addOverlay(new BMap.Polyline(pointsArr, {
      strokeColor : "red",
      strokeWeight : 3,
      strokeOpacity : 0.5
    }));
    //如果小于1直接移动到下一点
    if (count < 1) {
      me._moveNext(++me.i);
      return;
    }
    me._intervalFlag = setInterval(function() {
      //两点之间当前帧数大于总帧数的时候,则说明已经完成移动
      if (currentCount >= count) {
        clearInterval(me._intervalFlag);
        //移动的点已经超过总的长度
        if(me.i > me._path.length){
          return;
        }
        //运行下一个点
        me._moveNext(++me.i);
      }else {
        currentCount++;
        let 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){
          let proPos = null;
          if(me.i - 1 >= 0){
            proPos = me._path[me.i - 1];
          }
          if(me._opts.enableRotation == true){
            me.setRotation(proPos,initPos,targetPos);
          }
          if(me._opts.autoView){
            if(!me._map.getBounds().containsPoint(pos)){
              me._map.setCenter(pos);
            }
          }
        }
        //正在移动
        me._marker.setPosition(pos);
        //设置自定义overlay的位置
        me._setInfoWin(pos);
      }
    },timer);
  };
    console.log(bmap, points)
    this.setMapZoom(bmap, points)
},

根据坐标集points设置百度地图

setMapZoom (map, points) {
    let view = map.getViewport(points),
        mapZoom = view.zoom,
        centerPoint = view.center
    map.centerAndZoom(centerPoint,mapZoom)
    if (this.dialogVisible) {
        this.mapPlay(map, points)
    }
},

轨迹动画的设置及播放动画

mapPlay(map,points){
    //创建路书
    let icon = img_forklift
    //因为是单一弹窗播放,所以用var来全局控制
    var trackAni = new BMapLib.LuShu(map,points,{
    defaultContent:'叉车',//路书展示内容
    autoView:true,//是否开启自动视野调整
    //图标设置
    icon  : new BMap.Icon(icon, new BMap.Size(44,44),{anchor : new BMap.Size(22, 22)}),
    speed: this.speed,//速度
    enableRotation:true,//是否设置marker随着道路的走向进行旋转
    landmarkPois:[
       //停顿点   html 展示内容   pauseTime 停留时间 1s
       // {lng:116.363364,lat:39.920393,html:'测试点',pauseTime:1}
     ]
  });
  this.points=points
  this.map=map
  this.trackAni = trackAni
  trackAni.start();
},

暂停和播放功能

playMap () {
    let { play, trackAni } = this
    if (!play) {
      trackAni.start()
        this.play = true
    } else {
      trackAni.pause()
        this.play = false
    }
},

速度控制

speedChange(){
  this.trackAni._opts.speed = this.speed
}

核心功能和代码如上所示,下面是效果截图
界面
轨迹1
轨迹2
大功告成!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值