vue2 реализует компонент воспроизведения траектории Gaode Map JSAPI 2.0 (MoveAnimation)

vue2 реализует компонент воспроизведения траектории Gaode Map JSAPI 2.0 (MoveAnimation)

Отказ от ответственности: я работаю над серверной частью Java, поэтому, пожалуйста, простите меня, если извлечение компонентов не очень стандартизировано.

Предварительное условие: вам необходимо зарегистрироваться на открытой платформе Amap, затем создать приложение и активировать Web端(JS API)платформу, а затем securityJsCodeполучитьkey

Эффект реализации:

изображение-20230504111101438

1. Базовая экстракция

Уведомление:

  • Просто измените securityJsCodeи keyна свой собственный
  • v-show="true"Он отображается на панели управления. Когда я устанавливаю для него значение true при извлечении основ, он всегда будет отображаться.

Код компонента:

<template>
  <div>
    <a-row>
      <div id="container"></div>
      <div class='input-card' v-show="true">
        <div class="input-item">
          <a-button type="primary" size="small" style="width: 90px" @click="startAnimation">
            开始动画
          </a-button>
        </div>

        <div class="input-item">
          <a-button type="primary" size="small" style="width: 90px" @click="pauseAnimation">
            暂停动画
          </a-button>
        </div>

        <div class="input-item">
          <a-button type="primary" size="small" style="width: 90px" @click="resumeAnimation">
            继续动画
          </a-button>
        </div>

        <div class="input-item">
          <a-button type="primary" size="small" style="width: 90px" @click="stopAnimation">
            停止动画
          </a-button>
        </div>

      </div>
    </a-row>

  </div>

</template>

<script>
  //这里可以导入其他文件(比如: 组件, 工具 js, 第三方插件 js, json文件, 图片文件等等)
  //例如: import 《组件名称》 from '《组件路径》 ';

  import AMapLoader from "@amap/amap-jsapi-loader";
  // 设置安全密钥
  window._AMapSecurityConfig = {
    
    
    securityJsCode: 'xxxx',
  }
  export default {
    
    
    name: 'TrackContainer',
    //import 引入的组件需要注入到对象中才能使用
    components: {
    
    },
    props: {
    
    
      visible: Boolean,
    },
    data() {
    
    
      //这里存放数据
      return {
    
    
        AMap: null,
        //此处不声明 map 对象,可以直接使用 this.map赋值或者采用非响应式的普通对象来存储。
        map: null,
        mouseTool: null,
        marker: null,
        lineArr: [],
      };
    },
    //计算属性 类似于 data 概念
    computed: {
    
    },
    //监控 data 中的数据变化
    watch: {
    
    
    },
    //方法集合
    methods: {
    
    
      pauseAnimation () {
    
    
        this.marker.pauseMove();
      },
      resumeAnimation () {
    
    
        this.marker.resumeMove();
      },
      stopAnimation () {
    
    
        this.marker.stopMove();
      },
      startAnimation () {
    
    
        this.marker.moveAlong(this.lineArr, {
    
    
          // 每一段的时长
          duration: 500,//可根据实际采集时间间隔设置
          // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
          autoRotation: true,
        });
      },
      initMap() {
    
    
        AMapLoader.load({
    
    
          key: "xxxx",             // 申请好的Web端开发者Key,首次调用 load 时必填
          version: "2.0",      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
          "plugins": [
            "AMap.Scale",
            "AMap.HawkEye",
            "AMap.ToolBar",
            "AMap.AutoComplete",
            "AMap.PlaceSearch",
            "AMap.ControlBar",
            "AMap.MouseTool",
            "AMap.DragRoute",
            "AMap.MoveAnimation"],         // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        }).then((AMap) => {
    
    
          this.AMap=AMap
          this.marker=null;
          this.lineArr = [[116.478935,39.997761],[116.478939,39.997825],[116.478912,39.998549],[116.478912,39.998549],[116.478998,39.998555],[116.478998,39.998555],[116.479282,39.99856],[116.479658,39.998528],[116.480151,39.998453],[116.480784,39.998302],[116.480784,39.998302],[116.481149,39.998184],[116.481573,39.997997],[116.481863,39.997846],[116.482072,39.997718],[116.482362,39.997718],[116.483633,39.998935],[116.48367,39.998968],[116.484648,39.999861]];
          this.map = new AMap.Map("container", {
    
      //设置地图容器id
            viewMode: "2D",  //  是否为3D地图模式
            zoom: 13,   // 初始化地图级别
            center: [116.478935,39.997761], //中心点坐标  成都 104.065735, 30.659462
            resizeEnable: true
          });

          this.marker = new AMap.Marker({
    
    
            map: this.map,
            position: [116.478935,39.997761],
            icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
            offset: new AMap.Pixel(-13, -26),
          });

          // 绘制轨迹
          var polyline = new AMap.Polyline({
    
    
            map: this.map,
            path: this.lineArr,
            showDir:true,
            strokeColor: "#28F",  //线颜色
            // strokeOpacity: 1,     //线透明度
            strokeWeight: 6,      //线宽
            // strokeStyle: "solid"  //线样式
          });

          var passedPolyline = new AMap.Polyline({
    
    
            map: this.map,
            strokeColor: "#AF5",  //线颜色
            strokeWeight: 6,      //线宽
          });

          this.marker.on('moving', function (e) {
    
    
            passedPolyline.setPath(e.passedPath);
            this.map.setCenter(e.target.getPosition(),true)
          }.bind(this));

          this.map.setFitView();




        }).catch(e => {
    
    
          console.log(e);
        })
      },
    },
    //生命周期 - 创建完成(可以访问当前 this 实例)
    created() {
    
    
    },
    //生命周期 - 挂载完成(可以访问 DOM 元素)
    mounted() {
    
    
      this.initMap();
    },
    //生命周期 - 创建之前
    beforeCreate() {
    
    
    },
    //生命周期 - 挂载之前
    beforeMount() {
    
    
    },
    //生命周期 - 更新之前
    beforeUpdate() {
    
    
    },
    //生命周期 - 更新之后
    updated() {
    
    
    },
    //生命周期 - 销毁之前
    beforeDestroy() {
    
    
    },
    //生命周期 - 销毁完成
    destroyed() {
    
    
    },
    //如果页面有 keep-alive 缓存功能, 这个函数会触发
    activated() {
    
    
    },
  }
</script>

<style scoped>
  #container {
    
    
    padding: 0px;
    margin: 0px;
    width: 100%;
    height: 800px;
  }
  .input-item {
    
    
    height: 2.2rem;
  }

  .input-card {
    
    
    display: flex;
    flex-direction: column;
    min-width: 0;
    word-wrap: break-word;
    background-color: #fff;
    background-clip: border-box;
    border-radius: .25rem;
    width: 10rem;
    border-width: 0;
    border-radius: 0.4rem;
    box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
    position: fixed;
    bottom: 12rem;
    right: 2rem;
    -ms-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 0.75rem 1.25rem;
  }
</style>

2. Основная добыча и использование

изображение-20230504111402678

3. Расширенный индивидуальный маршрут извлечения

Идея:

  • Передайте переменную пути lineArr через родительский компонент вместо жесткого кодирования ее в дочернем компоненте.
    • Принимая во внимание проблемы с производительностью ( поскольку необходимо запрашивать lineArr всех устройств при просмотре родительского компонента, но если пользователь просматривает только один, будет потеря производительности ), поэтому я не lineArrпередал его напрямую дочернему компоненту. компонент через родительский компонент. Я сделал. Он будет передан дочернему компоненту через родительский компонент equipmentId, а затем дочерний компонент equipmentIdможет запросить соответствующее устройство, вызвав внутренний интерфейс lineArr( читатель может напрямую передать lineArr, без проблем )
  • При этом панель управления отображается через родительский компонент.v-show="visible"
  • В то же время я также добавил в компонент функцию выбора даты, которая может запрашивать путь определенного устройства в определенный день.
    • Конечно, из-за различий в бизнесе внутренний интерфейс необходимо писать самостоятельно, но общее возвращаемое значение равно одному.lineArr

Описание кода:

  • getTrackListМетод — это внутренний интерфейс, который я вызываю

  • Настройки карты и начальной точки автомобиля

    изображение-20230504114523273

Код компонента:

<template>
  <div>
    <a-row>
      <div id="container"></div>
      <div class='input-card' v-show="visible">
        <div class="input-item">
          <a-button type="primary" size="small" style="width: 90px" @click="startAnimation">
            开始动画
          </a-button>
        </div>

        <div class="input-item">
          <a-button type="primary" size="small" style="width: 90px" @click="pauseAnimation">
            暂停动画
          </a-button>
        </div>

        <div class="input-item">
          <a-button type="primary" size="small" style="width: 90px" @click="resumeAnimation">
            继续动画
          </a-button>
        </div>

        <div class="input-item">
          <a-button type="primary" size="small" style="width: 90px" @click="stopAnimation">
            停止动画
          </a-button>
        </div>

        <div class="input-item">
          <a-date-picker @change="onChange" />
        </div>


      </div>
    </a-row>

  </div>

</template>

<script>
  //这里可以导入其他文件(比如: 组件, 工具 js, 第三方插件 js, json文件, 图片文件等等)
  //例如: import 《组件名称》 from '《组件路径》 ';

  import AMapLoader from "@amap/amap-jsapi-loader";
  import moment from "moment";
  import {
    
    getTrackList} from '@/services/attendance/statistics.js'
  // 设置安全密钥
  window._AMapSecurityConfig = {
    
    
    securityJsCode: 'xxxxx',
  }
  export default {
    
    
    name: 'TrackContainer',
    //import 引入的组件需要注入到对象中才能使用
    components: {
    
    },
    props: {
    
    
      visible: Boolean,
      equipmentId: String,
    },
    data() {
    
    
      //这里存放数据
      return {
    
    
        AMap: null,
        //此处不声明 map 对象,可以直接使用 this.map赋值或者采用非响应式的普通对象来存储。
        map: null,
        mouseTool: null,
        marker: null,
        lineArr: [],
      };
    },
    //计算属性 类似于 data 概念
    computed: {
    
    },
    //监控 data 中的数据变化
    watch: {
    
    
    },
    //方法集合
    methods: {
    
    
      getLineArr(equipmentId, date) {
    
    
        getTrackList(equipmentId,date).then(res => {
    
    
          this.lineArr = res.data.data
          this.initTrackBefore(this.AMap);
        })
      },
      initTrack () {
    
    
        this.map = new AMap.Map("container", {
    
      //设置地图容器id
          viewMode: "2D",  //  是否为3D地图模式
          zoom: 13,   // 初始化地图级别
          center: this.lineArr[0], //中心点坐标  成都 104.065735, 30.659462
          resizeEnable: true
        });

        this.marker = new AMap.Marker({
    
    
          map: this.map,
          position: this.lineArr[0],
          icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
          offset: new AMap.Pixel(-13, -26),
        });

        // 绘制轨迹
        var polyline = new AMap.Polyline({
    
    
          map: this.map,
          path: this.lineArr,
          showDir: true,
          strokeColor: "#28F",  //线颜色
          // strokeOpacity: 1,     //线透明度
          strokeWeight: 6,      //线宽
          // strokeStyle: "solid"  //线样式
        });

        var passedPolyline = new AMap.Polyline({
    
    
          map: this.map,
          strokeColor: "#AF5",  //线颜色
          strokeWeight: 6,      //线宽
        });
        this.marker.on('moving', function (e) {
    
    
          passedPolyline.setPath(e.passedPath);
          this.map.setCenter(e.target.getPosition(), true)
        }.bind(this));

        this.map.setFitView();
      },
      onChange(date, dateString) {
    
    
        console.log(date, dateString);
        this.getLineArr(this.equipmentId,date.valueOf())
      },
      pauseAnimation () {
    
    
        this.marker.pauseMove();
      },
      resumeAnimation () {
    
    
        this.marker.resumeMove();
      },
      stopAnimation () {
    
    
        this.marker.stopMove();
      },
      startAnimation () {
    
    
        this.marker.moveAlong(this.lineArr, {
    
    
          // 每一段的时长
          duration: 500,//可根据实际采集时间间隔设置
          // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
          autoRotation: true,
        });
      },
      initTrackBefore (AMap) {
    
    
        if (this.lineArr.length > 0) {
    
    
          this.initTrack();
        } else {
    
    
          this.$message.error("该设备在当天无定位信息")
          this.map = new AMap.Map("container", {
    
      //设置地图容器id
            viewMode: "2D",  //  是否为3D地图模式
            zoom: 13,   // 初始化地图级别
            center: [104.065735, 30.659462], //中心点坐标  成都 104.065735, 30.659462
            resizeEnable: true
          });
          this.map.setFitView();
        }
      },
      initMap() {
    
    
        AMapLoader.load({
    
    
          key: "xxxx",             // 申请好的Web端开发者Key,首次调用 load 时必填
          version: "2.0",      // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
          "plugins": [
            "AMap.Scale",
            "AMap.HawkEye",
            "AMap.ToolBar",
            "AMap.AutoComplete",
            "AMap.PlaceSearch",
            "AMap.ControlBar",
            "AMap.MouseTool",
            "AMap.DragRoute",
            "AMap.MoveAnimation"],         // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        }).then((AMap) => {
    
    
          this.AMap=AMap
          this.marker=null;
          // this.lineArr = [[116.478935,39.997761],[116.478939,39.997825],[116.478912,39.998549],[116.478912,39.998549],[116.478998,39.998555],[116.478998,39.998555],[116.479282,39.99856],[116.479658,39.998528],[116.480151,39.998453],[116.480784,39.998302],[116.480784,39.998302],[116.481149,39.998184],[116.481573,39.997997],[116.481863,39.997846],[116.482072,39.997718],[116.482362,39.997718],[116.483633,39.998935],[116.48367,39.998968],[116.484648,39.999861]];
          this.initTrackBefore(AMap);





        }).catch(e => {
    
    
          console.log(e);
        })
      },
    },
    //生命周期 - 创建完成(可以访问当前 this 实例)
    created() {
    
    
      this.getLineArr(this.equipmentId,moment().valueOf())
    },
    //生命周期 - 挂载完成(可以访问 DOM 元素)
    mounted() {
    
    
      this.initMap();
    },
    //生命周期 - 创建之前
    beforeCreate() {
    
    
    },
    //生命周期 - 挂载之前
    beforeMount() {
    
    
    },
    //生命周期 - 更新之前
    beforeUpdate() {
    
    
    },
    //生命周期 - 更新之后
    updated() {
    
    
    },
    //生命周期 - 销毁之前
    beforeDestroy() {
    
    
    },
    //生命周期 - 销毁完成
    destroyed() {
    
    
    },
    //如果页面有 keep-alive 缓存功能, 这个函数会触发
    activated() {
    
    
    },
  }
</script>

<style scoped>
  #container {
    
    
    padding: 0px;
    margin: 0px;
    width: 100%;
    height: 800px;
  }
  .input-item {
    
    
    height: 2.2rem;
  }

  .input-card {
    
    
    display: flex;
    flex-direction: column;
    min-width: 0;
    word-wrap: break-word;
    background-color: #fff;
    background-clip: border-box;
    border-radius: .25rem;
    width: 10rem;
    border-width: 0;
    border-radius: 0.4rem;
    box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
    position: fixed;
    bottom: 12rem;
    right: 2rem;
    -ms-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 0.75rem 1.25rem;
  }
</style>

4. Расширенное извлечение и использование

  • trackVisibleВам нужно только синхронизировать отображение компонента карты в родительском компоненте, чтобы добиться синхронного переключения с компонентом карты.
  • Вам нужно только передать эти два значения родительскому компоненту.Если это lineArr, вам нужно изменить компонент и передать lineArr напрямую.
      <Track-Container
        :visible="trackVisible"
        :equipmentId ="form.equipmentImei"
      >
      </Track-Container>

Эффект следующий:

изображение-20230504113726303

Supongo que te gusta

Origin blog.csdn.net/qq_31745863/article/details/130484253
Recomendado
Clasificación