Bootstrap

Vue使用百度地图绘制人员历史轨迹

Vue使用百度地图绘制人员历史轨迹

在这里插入图片描述

使用

1.index.html 中引入百度地图在线链接

<!DOCTYPE html>
<html lang="zh-CH">

<head>
  <meta charset="utf-8">
  <!--必须要加 启用360浏览器的极速模式-->
  <meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1" />
  <meta name="renderer" content="webkit" />
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="./logo.png">
  <!-- 引入百度地图在线链接 -->
 <link rel="stylesheet" href="//api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css" />
  <script src="//api.map.baidu.com/api?type=webgl&v=3.0&ak=AWiSVwyAuNmbrhuNq1hjXAZV1SjmX3ld"></script>
  <script type="text/javascript" src="//api.map.baidu.com/library/TrackAnimation/src/TrackAnimation_min.js"></script>

  <!-- 按需加载外部的cdn 资源 -->
  <% if(htmlWebpackPlugin.options.isProd) { %>
    <script src="https://cdn.bootcss.com/vue/2.5.3/vue.js"></script>
  <!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  <!-- <link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.8.2/theme-chalk/index.css" /> -->
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/nprogress.css">
  <!-- 引入cdn 解决首次加载缓慢 -->
  <!-- <script src="https://cdn.staticfile.org/element-ui/2.8.2/index.js"></script> -->
  <script src="https://unpkg.com/[email protected]/nprogress.js"></script>
  <script src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
  <!-- element-ui 的 js 文件 -->
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.16.7/cpexcel.min.js"></script>
<% } %>
<script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js"></script>
  <title><%= htmlWebpackPlugin.options.isProd ? '采集员培训管理系统':'dev-测试环境' %> </title>
</head>
<body>
  <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
      Please enable it to continue.</strong>
  </noscript>
  <div id="app">
  </div>
</body>
</html>

2.具体页面中使用

<template>
  <div class="home">
    <section class="mainbox">
      <div class="content" >
        <div id="map_wrap" :style="{ height: mapHeight }">
          <!--存放百度地图容器-->
          <div id="container"></div>
        </div>
      </div>
    </section>
  </div>
</template>

<script>
//如果页面显示不出来地图的话,创建个baidu-map.js  文件, 文件内容在最后。
import BaiduMap from "../plugins/baidu-map";
import { getusers, select_user_Trajectorys } from "../api/api";

export default {
  name: "Home",
  components: {},
  data() {
    return {
      user:{},
      showTime: "",
      totlaNum: "",
      t: "",
      activeName: "first",
      caseTime: "",
      loading: false,
      showTrack: false,
      showTrackFun: "",
      caseTitile: 98,
      map: "", // 保存地图实例
      centerLng: "120.126532", // 经度
      centerLat: "30.282949", // 纬度
      shows: true,
      adminForm: {
        sdate: "",
        edate: "",
        speed: 1,
      },
      user_icon: "",
      polygon: {},
      leftpeopleList: [],
      /* 点聚合数组 */
      markers: [],
      peopleNum: 0,
      imagesrc: "../assets/logo.png",
      path: [],
      lushu: {},
      speed: 20, //速度
      lushu: {}, //路书
      mycaiId: "",
      myMap: {}, //地图,
      dotMarker: [],
      presentPeople: {},
      searchValue: "",
      polyline: [],
      mapHeight:0
    };
  },
  created() {
    this.t = setTimeout(this.time, 1000);
    this.user=JSON.parse(sessionStorage.getItem('user')) 
    console.log(this.user);
  },
  mounted() {
    this.initMapHeight()
    this.timing();
    this.timingUpdate();
  },

  methods: {
    initMap() {
      BaiduMap.init().then((BMap) => {
        this.getdata("-1");
        console.log("加载成功...");
      });
    },
	//初始化百度地图,创建地图对象
    createMap() {
      this.dotMarker = [];
      // 在百度地图容器中创建地图实例
      let map = new BMap.Map("container");
      // 将map变量存储在全局
      this.map = map;
      map.clearOverlays();
      // 设置中心点坐标和地图级别
      this.map.centerAndZoom(
        new BMap.Point(this.centerLng, this.centerLat),
        15
      );
      //获取地图中心点
       // //创建地址解析器实例
        var myGeo = new BMap.Geocoder();
        // 将地址解析结果显示在地图上,并调整地图视野
        myGeo.getPoint(this.user.gsaddress, (point)=>{
            if(point){
               this.map.centerAndZoom(point, 12);
               let icon= new BMapGL.Icon("../assets/img/command/star.png", new BMapGL.Size(52, 26));
               let marker = new BMap.Marker(point, {
                icon: icon,
              });
              setTimeout(() => {
                  map.addOverlay(marker);
              }, 100);
            }else{
                alert('您选择的地址没有解析到结果!');
            }
        })
      // 允许滚轮缩放
      this.map.enableScrollWheelZoom(true);
      // 设置地图默认缩放比例
      this.map.setZoom(12);
	//自定义地图显示内容
      map.setMapStyle({
        styleJson: [
          // {
          //   featureType: "road",
          //   elementType: "all",
          //   stylers: {
          //     color: "#ffffff",
          //     visibility: "off",
          //   },
          // },
          // {
          //   featureType: "building",
          //   elementType: "all",
          //   stylers: {
          //     visibility: "off",
          //   },
          // },
          // {
          //   featureType: "poilabel",
          //   elementType: "all",
          //   stylers: {
          //     visibility: "off",
          //   },
          // },
          // {
          //   featureType: "manmade",
          //   elementType: "all",
          //   stylers: {
          //     visibility: "off",
          //   },
          // },
        ],
      });
      // 百度地图marker样式
      this.user_icon = new BMap.Icon(
        require("../assets/img/command/user_isonline.png"),
        new BMap.Size(30, 36),
        {
          //当标注显示在地图上时,其所指向的地理位置距离图标左上角各偏移10像素和36像素
          anchor: new BMap.Size(10, 26),
          // 设置图片偏移,类似于剪切图片的功能
          imageOffset: new BMap.Size(0, 0),
        }
      );
      this.offLine_user_icon = new BMap.Icon(
        require("../assets/img/command/user_unonline.png"),
        new BMap.Size(30, 36),
        {
          //当标注显示在地图上时,其所指向的地理位置距离图标左上角各偏移10像素和36像素
          anchor: new BMap.Size(10, 26),
          // 设置图片偏移,类似于剪切图片的功能
          imageOffset: new BMap.Size(0, 0),
        }
      );
      this.leftpeopleList.forEach((v) => {
        // 创建坐标点
        if(v.lon){
          let points = new BMap.Point(v.lon, v.lat);
          if (v.isonline == 0) {
            //在线
            this.markerFun(map, points, this.user_icon, v);
          } else {
            this.markerFun(map, points, this.offLine_user_icon, v);
          }
        }
      });
      /* 添加地图控件 */
      var top_right_navigation = new BMap.NavigationControl({
        anchor: BMAP_ANCHOR_BOTTOM_RIGHT,
        type: BMAP_NAVIGATION_CONTROL_ZOOM,
        offset: new BMap.Size(30, 50),
      }); //右上角,仅包含平移和缩放按钮
      map.addControl(top_right_navigation);
    //添加地图标记点
    markerFun(map, point, icon, user, isInit) {
      let marker = new BMap.Marker(point, {
        icon: icon,
      });
      map.addOverlay(marker);
      this.dotMarker.push(marker);
      var content =
        '<div style="margin-top:5px;line-height:24px;padding:2px;">' +
        '<table border="0" class="table" style="width:440px;height:190px;font-size:14px;"><tbody><tr style="background-color: #29537b;text-align: left;"><th colspan="5" style="padding: 2px 0;color: #ffffff;"><span>&nbsp;&nbsp;|采集员信息</span><i οnclick="CloseInfoBox();"class="fa fa-times fr"></i></th></tr><tr style="margin:5px 0;"><td style="width:71px;">姓 名</td><td>' +
        user.name +
        '</td><td style="width:71px;">年龄</td><td>' +
        user.age +
        '</td><td id="userimg" rowspan="6" style="text-align:center;width:100px;"><img src="' +
        user.img +
        '" style="width:100px;height:130px;vertical-align: middle;margin-top:-26px;"></td></tr><tr style="background-color: #f5f9fc;"><td>电话</td><td>' +
        user.phone +
        "</td><td>性别</td><td>" +
        user.xb +
        '</td></tr><tr><td>登录时间</td><td colspan="3">' +
        user.logindate +
        '</td></tr><tr style="background-color: #f5f9fc;"><td>位置更新</td><td colspan="3">' +
        user.updatedate +
        '</td></tr><tr><td style="text-align:right;cursor: pointer;padding-top: 6px;padding-right:120px;" colspan="5"><a id="btn1" ' +
        "οnclick=aClick" +
        ' style="color:#22436b;">&gt;&gt;巡查轨迹</a></td></tr></tbody></table>' +
        "</div><script>";
      marker.addEventListener("click", (e) => {
        clearInterval(this.showTrackFun);
        this.presentPeople = user;
        var infoWindow = new BMap.InfoWindow(content, {
          width: 450, //宽度
          height: 200, //高度
        }); // 创建信息窗口对象
        this.map.openInfoWindow(infoWindow, point); //开启信息窗口
        setTimeout(() => {
          document.getElementById("btn1").onclick = () => {
            this.adminForm.sdate = this.time() + "00:00:00";
            this.adminForm.edate = this.time() + "23:59:59";
            this.adminForm.uid = user.id;
            this.mycaiId = user.name;
            this.showTrack = true;
            this.trajectory(user);
          };
        }, 100);
      });
    },

    //人员运动轨迹
    trajectory(user) {
      this.path = [];
      this.map.clearOverlays();
      select_user_Trajectorys({
        uid: user.id,
        // uid: 20,
        sdate: this.adminForm.sdate,
        edate: this.adminForm.edate,
      }).then((res) => {
        console.log(res);
        if (res.responseCode == 0) {
          if (res.data.length > 1) {
            let startPoint = res.data[0];
            let endPoint = res.data.pop();
            this.path = res.data;
            this.map.closeInfoWindow();
            this.map.centerAndZoom(new BMap.Point(user.lon, user.lat), 15);
            ///画出运动轨迹
            let pointArr = []; //坐标数组, 用于划线 维度lat,经度lng
            let pointEnd = null; //最后的点 point
            this.path.map((v, i) => {
              
              let point = new BMap.Point(v.lon, v.lat);
                pointArr.push(point);
                if (i === this.path.length - 1) {
                  pointEnd = new BMap.Point(v.lon, v.lat);
                }
            });
            let polyline = new BMap.Polyline(pointArr, {
              // strokeColor: "#2a537c",
              strokeColor: "red",
              strokeWeight: 3,
              strokeOpacity: 0.7,
            });

            this.polyline = polyline;
            //画出运动轨迹
            this.map.addOverlay(polyline);
            //添加最后时间的人员位置
            let marker = new BMap.Marker(pointEnd, {
              icon: this.user_icon,
            });
            this.map.addOverlay(marker);
            this.dotMarker.push(marker);
            //画轨迹结束
            BMapLib.LuShu.prototype._move = function(
              initPos,
              targetPos,
              effect
            ) {
              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
                );
              //显示折线 syj201607191107
              //如果想显示小车走过的痕迹,放开这段代码就行
              // this._map.addOverlay(
              //   new BMap.Polyline(pointsArr, {
              //     strokeColor: "#111",
              //     strokeWeight: 5,
              //     strokeOpacity: 0.5
              //   })
              // ); // 画线
              //如果小于1直接移动到下一点
              if (count < 1) {
                me._moveNext(++me.i);
                return;
              }
              me._intervalFlag = setInterval(() => {
                //两点之间当前帧数大于总帧数的时候,则说明已经完成移动
                if (currentCount >= count) {
                  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];
                    }
                    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);
            };

            this.initLushu(this.map, pointArr, this.mycaiId);
          } else {
            this.$message.error("暂无人员数据!");
          }
        } else {
          this.$message.error(res.message);
        }
      });
    },
    initLushu(map, arrPois, mycaiId) {
      console.log(this.speed);
      this.lushu = new BMapLib.LuShu(map, arrPois, {
        defaultContent: mycaiId, //"从天安门到百度大厦"
        autoView: true, //是否开启自动视野调整,如果开启那么路书在运动过程中会根据视野自动调整
        icon: this.user_icon,
        speed: this.speed,
        enableRotation: false, //是否设置marker随着道路的走向进行旋转
        landmarkPois: [
          // {
          //   lng: 116.306954,
          //   lat: 40.05718,
          //   html: "加油站",
          //   pauseTime: 2,
          // },
        ],
      });
    },


    play(val) {
      if (this.path.length > 3) {
        switch (val) {
          case 1:
            this.lushu.start();
            if (this.dotMarker.length > 0) {
              for (let i = 0; i < this.dotMarker.length; i++) {
                this.map.removeOverlay(this.dotMarker[i]);
              }
            }
            break;
          case 2:
            this.lushu.pause();
            break;
          case 3:
            this.lushu.stop();
            this.speed = 5;
            this.lushu._opts.speed = 5;
            break;
        }
      } else {
        this.$message.error("暂无人员数据!");
      }
    },
    //调整人员轨迹速度
    adjustSpeed(e) {
      this.lushu._opts.speed=20;
      this.lushu._opts.speed =this.lushu._opts.speed+ e * 20;
    },
    backTrack() {
      this.map.clearOverlays();
      this.showTrack = false;
      // 设置地图中心点
      let points = new BMap.Point(
        this.presentPeople.lon,
        this.presentPeople.lat
      );
      this.map.panTo(points);
      this.map.setZoom(12);
      if (this.presentPeople.isonline == 0) {
        //在线
        this.markerFun(this.map, points, this.user_icon, this.presentPeople);
      } else {
        this.markerFun(
          this.map,
          points,
          this.offLine_user_icon,
          this.presentPeople
        );
      }
      clearInterval(this.showTrackFun);
      this.timingUpdate();
    },
    
    timingUpdate() {
      if (!this.showTrack) {
        this.showTrackFun = setInterval(() => {
          this.timing();
          this.showTrack = false;
        }, 120000);
      }
    },

    handleClick(item, i) {
      this.leftpeopleList.forEach((v, index) => {
        index == i ? (v.active = true) : (v.active = false);
      });
      this.showTrack = false;
      if(item.lon){
        this.presentPeople = item;
      this.map.clearOverlays();
      // 设置地图中心点
      let points = new BMap.Point(
        this.presentPeople.lon,
        this.presentPeople.lat
      );
      this.map.panTo(points, { zoom: 10 });
      if (this.presentPeople.isonline == 0) {
        //在线
        this.markerFun(
          this.map,
          points,
          this.user_icon,
          this.presentPeople,
          true
        );
        this.map.addOverlay();
      } else {
        this.markerFun(
          this.map,
          points,
          this.offLine_user_icon,
          this.presentPeople,
          true
        );
      }
      }else{
        this.$message({
          message:'暂无人员信息',
          type:'success'
        })
      }
    },
    handle() {
      const path = sessionStorage.getItem("path") || "/organization/branch";
      if (sessionStorage.getItem("user") != undefined) {
        this.$router.push(path);
      } else {
        this.$router.push("/login");
      }
    },
    //右上角时间
    time() {
      clearTimeout(this.t); //清除定时器
      var dt = new Date();
      var y = dt.getFullYear();
      var mt = dt.getMonth() + 1;
      var day = dt.getDate();
      var h = dt.getHours(); //获取时
      var m = dt.getMinutes(); //获取分
      var s = dt.getSeconds(); //获取秒
      this.showTime =
        "当前时间:" +y +"年" +mt +"月" +day +"-" + h +"时" + m +"分" + s +"秒";
      this.t = setTimeout(this.time, 1000); //设定定时器,循环运行
      this.caseTime = y + "年" + mt + "月" + day;
      return y + "-" + mt + "-" + day + " ";
    },
    //定时更新数据
    timing() {
      this.initMap();
    },

    switchStatus(index) {
      switch (index) {
        case 1:
          this.getdata("0");
          break;
        case 2:
          this.getdata("1");
          break;
        case 3:
          this.getdata("-1");
          this.searchValue = "";
          break;
        default:
          break;
      }
    },

    /* 查询人员信息 */
    getdata(isonline) {
      let cid = "";
      window.JSON.parse(sessionStorage.getItem("user")).rid == 1
        ? (cid = -1)
        : (cid = window.JSON.parse(sessionStorage.getItem("user")).cid);
      getusers({
        pagenum: 1,
        pagesize: 3000,
        cid: cid,
        rid: 3,
        isonline: isonline,
      }).then((res) => {
        console.log(res);
        this.leftpeopleList = res.data.content;
        if (this.leftpeopleList) {
          this.createMap();
        }
        if (isonline == "-1") {
          getusers({
            pagenum: 1,
            pagesize: 3000,
            cid: cid,
            rid: 3,
            isonline: 0,
          }).then((res1) => {
            this.peopleNum = res1.data.content.length;
          });
        } else {
          this.peopleNum = res.data.content.length;
        }
      });
      getusers({
        pagenum: 1,
        pagesize: 3000,
        cid: cid,
        rid: 3,
        isonline: -1,
      }).then((res) => {
        console.log(res);
        this.totlaNum = res.data.content.length;
      });
    },
     initMapHeight(){
      let main= document.querySelector('#map_wrap')
      main.style.height=(window.innerHeight)+'px';
      window.onresize = () => {
        return (() => {
          if (window.innerWidth > 1664) {
            this.mapHeight = window.innerHeight + "px";
          } else {
            this.mapHeight = window.innerHeight+ "px";
          }
        })();
      };
    },
  },
  beforeDestroy() {
    clearInterval(this.showTrackFun);
  },
};
</script>

BaiduMap.js

/*
 * @Descripttion: 
 * @version: 
 * @Author: ph zhai
 * @Date: 2021-03-11 17:27:39
 * @LastEditors: Andy
 * @LastEditTime: 2021-04-21 10:45:52
 */
 const BaiduMap={
    init: function (){
      console.log("初始化百度地图脚本...");
      const AK = "iBOzpLdrEyOEaaS3I27CkRLZ7rBizeCE";
      const apiVersion = "3.0";
      const timestamp = new Date().getTime();
      // const BMap_URL = "http://api.map.baidu.com/getscript?v="+ apiVersion +"&ak="+ AK +"&services=&t=" + timestamp+"&s=1";

      const BMap_URL = "http://api.map.baidu.com/getscript?v="+ apiVersion +"&ak="+ AK +"&s=1";
      const HMap_URL = "http://api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js";
      const LuShu = "http://api.map.baidu.com/library/LuShu/1.2/src/LuShu_min.js";
      return new Promise((resolve, reject) => {
        if(typeof BMap !== "undefined") {
          resolve(BMap);
          return true;
        }
  
        let scriptNode = document.createElement("script");
        scriptNode.setAttribute("type", "text/javascript");
        scriptNode.setAttribute("src", BMap_URL);
        document.body.appendChild(scriptNode);

        setTimeout(()=>{
          let scriptNode3 = document.createElement("script");
        scriptNode3.setAttribute("type", "text/javascript");
        scriptNode3.setAttribute("src", LuShu);
        document.body.appendChild(scriptNode3);
        },300)


        let scriptNode1 = document.createElement("script");
        scriptNode1.setAttribute("type", "text/javascript");
        scriptNode1.setAttribute("src", 'http://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js');
        document.body.appendChild(scriptNode1);

        let scriptNode2 = document.createElement("script");
        scriptNode2.setAttribute("type", "text/javascript");
        scriptNode2.setAttribute("src", 'http://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js');
        document.body.appendChild(scriptNode2);

  
        // 等待页面加载完毕回调
        let timeout = 0;
        let interval = setInterval(() => {
          // 超时10秒加载失败
          if(timeout >= 20) {
            reject();
            clearInterval(interval);
            console.error("百度地图脚本初始化失败...");
          }
          // 加载成功
          if(typeof BMap !== "undefined") {
            resolve(BMap);
            clearInterval(interval);
            console.log("百度地图脚本初始化成功...");
          }
          timeout += 1;
        }, 500);
      });
    }
  }  
  export default BaiduMap
;