前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在 vue/cli 中使用百度地图 js api

在 vue/cli 中使用百度地图 js api

作者头像
4O4
发布2022-04-25 16:31:49
8160
发布2022-04-25 16:31:49
举报
文章被收录于专栏:404404

在 vue/cli 中使用百度地图 js api

写在前面

此前使用了 vue-baidu-map,由于业务需求不断迭代,该组件已经无法满足我的需求,并且源码本身就存在缺陷以及缺少维护,因此我选择改为使用百度地图js api。

百度地图js api最新版为3.0,另外有GL版,官方给出的说明是:GL版本接口基本向下兼容,迁移成本低。目前v1.0版本支持了基本的3D地图展示、基本地图控件和覆盖物。 但是我实测v_3.0和v_GL似乎并不是完整的向下兼容,这里我使用了 v2.0。

需求如下:

  1. 通过百度地图api获取用户的历史轨迹和实时轨迹。其中历史轨迹是通过查询该用户绑定的物联网设备上传到hbase的数据,实时轨迹则是通过订阅mq获得。
  2. 获取/绘制/修改/删除百度地图电子围栏。
  3. 查询自定义时间段轨迹。
  4. 文字轨迹。(地理位置解析、去重、计时)
  5. 地图debug模式。(轨迹点数据源类型、时间、时间差)

开始

引入地图

public/index.html

代码语言:javascript
复制
// 同步加载
<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak=您的密钥"></script>

// 异步加载
<script type="text/javascript"> 
function initialize() { 
  var mp = new BMapGL.Map('map'); 
  mp.centerAndZoom(new BMapGL.Point(121.491, 31.233), 11); 
} 
    
function loadScript() { 
  var script = document.createElement("script"); 
  script.src = "https://api.map.baidu.com/api?v=1.0&type=webgl&ak=您的密钥&callback=initialize";
  document.body.appendChild(script); 
} 
    
window.onload = loadScript; 
</script> 

map.vue

代码语言:javascript
复制
<template>
  <div>
    <v-card class="overflow-hidden">
      <div id="bmap"></div>
      
      <v-navigation-drawer v-model="textTrack" :right="true" absolute width="400px">
        <time-line></time-line>
      </v-navigation-drawer>
    </v-card>
  </div>
</template>

<script lang='ts'>
import { Component, Vue, Prop, Watch } from "vue-property-decorator";

@Component
export default class Map extends Vue {
  private textTrack: boolean = false;     // 文字轨迹开关
}

time-line.vue

代码语言:javascript
复制
<template>
  <v-card-text class="py-0">
    <h3 v-if="!show" style="margin: 3rem 0;">暂无数据</h3>

    <v-timeline v-else align-top dense style="text-align: left;">
      <v-timeline-item color="primary" small v-for="(item, index) in timelineList" :key="index">
        <v-row class="pt-1">
          <v-col cols="3">
            <strong>{{ tp(item.ts) }}</strong>
          </v-col>
          <v-col>
            <strong>
              {{ item.addr ? JSON.parse(`${item.addr}`)[0]['district'] : '-'}}
              <span>{{ `(停留${fl(item.stay)})` }}</span>
            </strong>
            <div class="caption">{{ item.addr ? JSON.parse(`${item.addr}`)[0]['name'] : '-'}}</div>
          </v-col>
        </v-row>
      </v-timeline-item>
    </v-timeline>
  </v-card-text>
</template>

<script lang='ts'>
import { Component, Vue, Prop, Watch } from "vue-property-decorator";
import axios from "axios";
import bus from "@/utils/bus";

@Component
export default class TimeLine extends Vue {
  show: boolean = false;
  timelineList: any = [];
  events: any = [];
  input: any = null;
  nonce: any = 0;

  get timeline() {
    return this.events.slice();
  }

  tp: any = function (timestamp: any, type?: any) {
    var date = new Date(Number(timestamp) * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
    var Y = date.getFullYear() + "-";
    var M =
      (date.getMonth() + 1 < 10
        ? "0" + (date.getMonth() + 1)
        : date.getMonth() + 1) + "-";

    function zeroH(h: number) {
      return h < 10 ? "0" + h + ":" : h + ":";
    }

    function zeroM(m: number) {
      return m < 10 ? "0" + m + ":" : m + ":";
    }

    function zeroS(s: number) {
      return s < 10 ? "0" + s : s;
    }

    var D = date.getDate() + " ";
    var h = zeroH(date.getHours());
    var m = zeroM(date.getMinutes());
    var s = zeroS(date.getSeconds());

    if (type === 'full') {
      return Y + M + D + h + m + s;
    } else {
      return h + m + s;
    }
  }

  comment() {
    const time = new Date().toTimeString();
    this.events.push({
      id: this.nonce++,
      text: this.input,
      time: time.replace(
        /:\d{2}\sGMT-\d{4}\s\((.*)\)/,
        (match, contents, offset) => {
          return ` ${contents
            .split(" ")
            .map((v: any) => v.charAt(0))
            .join("")}`;
        }
      )
    });

    this.input = null;
  }

  fl(num: number): any {
    if (num / 3600 < 1) {
      return `${Math.abs(Math.floor(num / 60))}分${Math.abs(
        Math.floor(num % 60)
      )}秒`;
    } else {
      return `${Math.abs(Math.floor(num / 3600))}时${Math.abs(
        Math.floor(Math.floor(num % 3600) / 60)
      )}分${Math.abs(Math.floor(num % 60))}秒`;
    }
  }

  deduplication(data: any): any {
    let _arr: any = [];

    data.forEach((item: any, index: number) => {
      if (index == 0) {
        item.stay = 0;
        _arr.push(item);
      } else if (index > 0) {
        try {
          item.stay = 0;
          if (
            JSON.parse(item.addr)[0].name !=
            JSON.parse(data[index - 1].addr)[0].name
          ) {
            _arr.push(item);
            console.log("写入" + index);
          } else {
            _arr[_arr.length - 1].stay +=
              Number(item.ts) - Number(data[index - 1].ts);
            console.log("重复" + index);
          }
        } catch (error) {
          console.log(error);
        }
      }
    });

    return _arr;
  }

  mounted() {
    bus.$on("list", (data: any) => {
      this.timelineList = this.deduplication(data);
      // .reverse();
      if (data.length > 0) {
        this.show = true;
      }
      console.log(data);
    });
  }
}
</script>

<style lang="scss" scoped>
</style>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-06-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在 vue/cli 中使用百度地图 js api
    • 写在前面
      • 开始
        • 引入地图
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档