vue2实现高德地图 JSAPI 2.0轨迹回放组件(MoveAnimation)

news2024/11/15 5:34:14

vue2实现高德地图 JSAPI 2.0轨迹回放组件(MoveAnimation)

声明: 本人是做java后端的,组件抽取不是很规范请大家见谅

前提: 需要注册高德开放平台,之后创建应用并且开通Web端(JS API)平台,然后拿到securityJsCodekey

实现效果:

image-20230504111101438

1. 基础抽取

注意:

  • securityJsCodekey修改为自己的即可
  • 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. 基础抽取使用

image-20230504111402678

3. 进阶抽取-自定义路线

思路:

  • 将lineArr路径变量通过父组件传过来,而不是在子组件写死
    • 考虑到性能问题(因为在父组件的时候就需要查询出所有设备的lineArr,但如果用户只查看一个就会有性能损耗),所以我没有直接将lineArr直接通过父组件直接传到子组件,我是通过父组件将equipmentId传到子组件,然后子组件通过equipmentId调用后端接口可以查询的对应设备的lineArr(读者可以直接将lineArr传过来也没问题)
  • 同时通过父组件来操作控制面板在展示v-show="visible"
  • 同时我还对组件新增了日期选择功能,可以查询到某个设备某天的路径轨迹
    • 当然因为业务的不同,后端接口需要自己来写,但总体的返回值就是一个lineArr

代码说明:

  • getTrackList方法为我调用的后端接口

  • 地图及小车起点设置

    image-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>

效果如下:

image-20230504113726303

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/487926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenGL(四)——纹理

目录 一、前言 二、纹理环绕方式 三、纹理过滤 3.1 邻近过滤 3.2 线性过滤 3.3 多级渐远纹理 四、加载、创建纹理 4.1 数据输入 4.2 生成并加载纹理 4.3 应用纹理坐标 4.4 顶点着色器配置纹理 4.5 片段着色器配置纹理 4.6 显示纹理 五、纹理单元 一、前言 为每个…

云原生技术概谈

云原生技术概谈 说起“云原生技术”&#xff0c;大家可能有点懵&#xff0c;只闻其声&#xff0c;不明其意。但是云原生背后典型的几个公司或者技术产品的名称可能大家经常听到&#xff1a; 比如容器技术的代表公司docker&#xff1b;容器编排技术开源产品kubernetes&#xff0…

推荐算法实战项目:DeepCross 原理以及案例实战(附完整 Python 代码)

本文要介绍的是由斯坦福大学联合Google的研究人员发表的论文《Deep & Cross Network for Ad Click Predictions》中提出的Deep&Cross模型&#xff0c;简称DCN。 DCN模型是Wide&Deep的改进版本&#xff0c;其中Deep部分的设计思路与Wide&Deep没有发生本质的变化…

计算机视觉的应用3-批量图片风格迁移之素描图片生成的应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用3-批量图片生成素描图片的应用&#xff0c;将一张图像转换为素描风格的图像的其实是模拟了人类视觉在观察物体时受到的光照条件。素描风格的图像在灰度值上表现出明暗交替的效果&#xff0c;这种效…

【干货】一文说透分布式一致性协议(下)

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"&#xff01; 作者&#xff1a;大能老师 | 慕课网讲师 前情提示&#xff1a;如需阅读“一文说透分布式一致性协议&#xff08;上&#xff09;”&#…

对多个点进行直线拟合操作

在图像处理中&#xff0c;通常会遇到根据给定的点集&#xff08;比如轮廓&#xff09;拟合出一条直线的情形。 import numpy as np import matplotlib.pyplot as plt import cv2def Cal_kb_linear_fitline(pointLocs):loc np.array(pointLocs) # loc 必须为矩阵形式&#xff…

二分类结局变量Logistic回归临床模型预测(二)——基线特征及三线表绘制(二)

本节讲的是二分类结局变量的临床模型预测,与之前讲的Cox回归不同,https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/124088364https://lijingxian19961016.blog.csdn.net/article/details/1300…

蓝牙耳机哪款性价比高一些?2023年性价比最高的蓝牙耳机推荐

随着科技的进步&#xff0c;蓝牙耳机已然成为我们生活中的一部分&#xff0c;无论是通勤、追剧、运动或者玩游戏&#xff0c;大都会用到蓝牙耳机。那么&#xff0c;哪款蓝牙耳机的性价比高一些&#xff1f;相信大多数人在选择产品的时候&#xff0c;都会看性价比。接下来&#…

手把手带你写一份优秀的开发求职简历(五)技术能力如何凸显优势

前言 前面的几小节&#xff0c;把个人信息和教育背景的模块做了讲述&#xff0c;这两个模块处于简历的第一屏最顶部&#xff0c;可以说HR会第一眼看见&#xff0c;所以很重要&#xff0c;同时也通过一些讲述告诉求职者从这些方面如何扬长避短&#xff0c;抓住HR的招聘心理。 …

Android基于JNA集成调用第三方C/C++的so库

Android基于JNA集成调用第三方C/C的so库 &#xff08;1&#xff09;引入JNA。 基于JNA开源项目&#xff0c;JNA对Android NDK的封装&#xff0c;简化Android层JNI集成调用C/C的so库。 GitHub - java-native-access/jna: Java Native AccessJava Native Access. Contribute to…

为AI造“楚门世界” 人类围观对话机器人社交、谈恋爱

不满足于跟ChatGPT聊天&#xff0c;技术狂人开始为对话机器人创造“楚门的世界”&#xff0c;从上帝视角围观AI如何“吃饭”、社交、谈恋爱...... 最近&#xff0c;一位神秘人创建了一个AI社交网站Chirper&#xff0c;人类不能参与&#xff0c;只能围观上万名AI在这里的聊天和…

社交技能讲座笔记

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 感谢张鹏老师做了一堂实用的社交技能讲座。我特地做了一些笔记&#xff08;其中包含我的一些理解&#xff09;&#xff1a; 1.整理好外观&#xff0c;让别…

【大数据之Hadoop】二十三、Yarn命令行操作及生产环境下的配置

1 Yarn常用命令 Yarn状态查询可以在hadoop103:8088页面查看&#xff0c;也可以通过命令查看。 先运行案例再查看运行情况。 &#xff08;1&#xff09;yarn application 查看任务 yarn application -list //列出所有application yarn application -list -appStates 状态 …

c++ 11标准模板(STL) std::vector (五)

定义于头文件 <vector> template< class T, class Allocator std::allocator<T> > class vector;(1)namespace pmr { template <class T> using vector std::vector<T, std::pmr::polymorphic_allocator<T>>; }(2)(C17…

Qt音视频开发43-采集屏幕桌面并推流(支持分辨率/矩形区域/帧率等设置/实时性极高)

一、前言 采集电脑屏幕桌面并推流一般是用来做共享桌面、远程协助、投屏之类的应用&#xff0c;最简单入门的做法可能会采用开个定时器或者线程抓图&#xff0c;将整个屏幕截图下来&#xff0c;然后将图片传出去&#xff0c;这种方式很简单但是性能要低不少&#xff0c;一般采…

R语言的贝叶斯时空数据模型

时间&#xff0d;空间数据&#xff08;以下简称“时空数据”&#xff09;是最重要的观测数据形式之一&#xff0c;很多科学研究的数据都以时空数据的形式得以呈现&#xff0c;而科学研究目的可以归结为挖掘时空数据中的规律。另一方面&#xff0c;贝叶斯统计学作为与传统统计学…

FCOS3D Fully Convolutional One-Stage Monocular 3D Object Detection 论文学习

论文地址&#xff1a;Fully Convolutional One-Stage Monocular 3D Object Detection Github地址&#xff1a;Fully Convolutional One-Stage Monocular 3D Object Detection 1. 解决了什么问题&#xff1f; 单目 3D 目标检测由于成本很低&#xff0c;对于自动驾驶任务非常重…

可视化工作流管理

​本场景是可视化工作流&#xff0c;通过可视化的精益看板将价值流进行可视化&#xff0c;通过精益思维消除瓶颈、加速流动&#xff0c;提升效率。 创建工作流任务看板 •通过Leangoo可视化工作流项目模板&#xff0c;创建一个工作流看板。 •通过看板&#xff0c;我们可以将…

K_A35_017 基于STM32等单片机驱动TTP229矩阵触摸传感器 串口与OLED0.96双显示

K_A35_017 基于STM32等单片机驱动TTP229矩阵触摸传感器 串口与OLED0.96双显示 所有资源导航一、资源说明二、基本参数参数引脚说明 三、驱动说明时序:对应程序: 四、部分代码说明1、接线引脚定义1.1、STC89C52RCTTP229矩阵触摸模块1.2、STM32F103C8T6TTP229矩阵触摸模块 五、基…

医院安全(不良)事件报告系统 PHP语言实现

医院安全&#xff08;不良&#xff09;事件报告制度 一、目的 规范医院安全&#xff08;不良&#xff09;事件的主动报告&#xff0c;增强风险防范意识&#xff0c;及时发现医疗不良事件和安全隐患&#xff0c;将获取的医疗安全信息进行分析反馈&#xff0c;并从医院管理体系…