VUE 前端笔记:使用 v-charts.js百度地图 实现电子围栏手机定位打卡 笔记

使用 v-charts.js百度地图 实现电子围栏手机定位打卡

关尔先生2020-10-21 11:38:03

1、设置一个公司的经纬度
2、设定打卡半径(圆形电子围栏)
3、时时获取定位
4、计算定位到公司的直线距离
5、对比 打卡半径>直线距离,打卡成功



DEMO:


<template>
  <div>
    <router-link to='/test' style="margin:16px">? 设置公司位置</router-link>
    <van-field v-model="addressPoint" readonly center clearable label="公司经纬度"></van-field>
    <van-field v-model="addressRadius" readonly center clearable label="打卡半径/米"></van-field>
    <van-field v-model="distance" readonly center clearable label="距离/米">
      <template #button>
        <van-button @click="mapShow=!mapShow" size="small" type="primary">{{mapShow?'隐藏地图':'显示地图'}}</van-button>
      </template>
    </van-field>
    <!-- 定位打卡 -->
    <ve-bmap
      v-show="mapShow"
      ref="VeBmapRef"
      :settings="chartSettings"
      :series="chartSeries"
      :tooltip="chartTooltip"
      :after-set-option-once="afterSet"
    ></ve-bmap>

    <div v-if="distance<addressRadius" @click="toSignFu" class="sign-btn-box flex flex-direction flex-center">
      <div class="sign-btn-title">打卡</div>
      <div class="sign-btn-time">{{thisTime}}</div>
    </div>
    <div v-else class="sign-btn-box flex flex-direction flex-center not-ready">
      <div class="sign-btn-title text-center small">
        未到达
        <br />考勤范围
      </div>
      <div class="sign-btn-time">{{thisTime}}</div>
    </div>
    <p class="tips">每{{frequency/1000}}秒更新一次定位,目前更新{{mark}}次</p>
  </div>
</template>
<script>
import Vue from "vue";
import context from "@/components/form/context";
import VeBmap from "v-charts/lib/bmap.common";
import { fmtTime } from "@/utils";

export default {
  components: {
    VeBmap,
  },
  data() {
    this.chartSettings = {
      key:"申请的百度地图key",
      bmap: {
        // 百度地图中心经纬度
        // center: [116.396428,39.917614],
        // 百度地图缩放
        zoom: 19,
        // 是否开启拖拽缩放,可以只设置 'scale' 或者 'move'
        roam: true,
        // 百度地图的自定义样式,见 http://developer.baidu.com/map/jsdevelop-11.htm
        mapStyle: {},
      },
    };
    this.chartTooltip = { show: true };
    return {
      addressPoint: "118.051301,24.619201",
      addressRadius: "500",
      // <!-- 定位打卡 -->
      mapShow: false,
      map: null, //百度地图实例对象
      zoom: 16,
      markOverlays: [],
      myPoint: { lng: 0, lat: 0 },
      distance: 9999,
      chartSeries: [
        {
          type: "scatter",
          // 使用百度地图坐标系
          coordinateSystem: "bmap",
          // 数据格式跟在 geo 坐标系上一样,每一项都是 [经度,纬度,数值大小,其它维度...]
          // data: [[120, 30, 1]],
        },
      ],
      thisTime: "23:59:59",
      thisTimer: null,
      frequency: 10000,
      mark: 0,
    };
  },
  computed: {
    companyPoint() {
      let _j = { lng: "", lat: "" };
      if (
        typeof this.addressPoint == "string" &&
        this.addressPoint.indexOf(",") > 0
      ) {
        let ar = this.addressPoint.split(",");
        _j.lng = ar[0] || 0;
        _j.lat = ar[1] || 0;
      }
      return _j;
    },
  },
  watch: {},
  created() {
    this.updateTitle(this.$route.meta.title);
    this.addressPoint =
      localStorage.getItem("addressPoint") || this.addressPoint;
    this.addressRadius =
      localStorage.getItem("addressRadius") || this.addressRadius;
    this.thisTimer = setInterval(() => {
      this.thisTime = fmtTime("HH:MM:SS", new Date());
    }, 1000);
  },
  destroyed() {
    clearInterval(this.thisTimer);
  },
  methods: {
    ...mapMutations({
      updateTitle: types.UPDATE_TITLE,
    }),
    toSignFu(){
     this.$dialog.alert({
        title: "打卡成功",
        message:this.thisTime
      });
    },
    afterSet(echarts) {
      let that = this;
      // 获取百度地图实例
      let map = echarts.getModel().getComponent("bmap").getBMap();
      this.map = map;

      // 使用百度地图自带的控件
      map.addControl(new window.BMap.MapTypeControl());

      // 初始化地图,设置中心点坐标和地图级别
      console.log(this.companyPoint);
      this.map.centerAndZoom(
        new window.BMap.Point(this.companyPoint.lng, this.companyPoint.lat),
        that.zoom
      );

      this.markCircle(this.companyPoint, this.addressRadius);

      this.getCurrentPosition();

      // 添加定位控件
      var geoCtrl = new BMap.GeolocationControl({
        showAddressBar: true, //是否显示
        enableAutoLocation: false, //首次是否进行自动定位
        offset: new BMap.Size(0, 25),
        //, locationIcon     : icon //定位的icon图标
      });
      //监听定位成功事件
      geoCtrl.addEventListener("locationSuccess", function (r) {
        console.log(r);
        that.myPoint = r.point;
        that.markPoint(r.point, "当前", true);
        // that.getAddress();
        // that.address.searchList = [];
      });
      //监听定位失败事件
      geoCtrl.addEventListener("locationError", function (e) {
        console.log(e);
      });
      // 将定位控件添加到地图
      map.addControl(geoCtrl);
    },

    clearAllOverlays() {
      // 百度地图API功能
      let map = this.map;
      this.markOverlays.forEach((overlay) => {
        map.removeOverlay(overlay);
      });
    },
    markPoint(point, label = "", go = false, doClear = true) {
      // 百度地图API功能
      let map = this.map;
      if (doClear) {
        this.clearAllOverlays();
      }
      var overlay = new BMap.Marker(point);
      if (label) overlay.setLabel(this.getLabel(label));

      map.addOverlay(overlay);
      this.markOverlays.push(overlay);
      if (go) {
        this.toPoint(point);
      }
    },
    /**
     * 画圆
     * point 圆心 经纬度
     * radius 半径,单位/米
     */
    markCircle(point, radius) {
      console.log(point);
      // 百度地图API功能
      let map = this.map;
      //创建圆对象
      let circle = new BMap.Circle(point, radius, {
        strokeColor: "blue",
        strokeWeight: 1,
        fillColor: "#E2E8F1",
        fillOpacity: 0.6,
      });
      console.log(circle);
      //画到地图上面
      map.addOverlay(circle);

      console.log(circle.getRadius());
    },
    markLine(points) {
      let num = points.length;
      let pointObjs = [];
      for (let i = 0; i < num; i++) {
        let point = points[i];
        pointObjs.push(new BMap.Point(point.lng, point.lat));
      }
      // 百度地图API功能
      let map = this.map;
      var polyline = new BMap.Polyline(pointObjs, {
        strokeColor: "blue",
        strokeWeight: 2,
        strokeOpacity: 0.5,
      });
      map.addOverlay(polyline);

      this.distance = map.getDistance(pointObjs[0], pointObjs[1]);
    },
    getLabel(content) {
      let fontSize = 12;
      let len = content.length * fontSize;

      //左偏移  右偏移

      var labelStyle = {
        color: "#fff",
        backgroundColor: "#333333",
        border: "0",
        fontSize: fontSize + "px",
        width: len + "px",
        opacity: "0.8",
        textAlign: "center",
        verticalAlign: "center",
        borderRadius: "2px",
        whiteSpace: "normal",
        wordWrap: "break-word",
        padding: "2px 4px",
      };
      //用于设置样式
      var spanA = "<span class='angle'><span>";
      //不同数字长度需要设置不同的样式。
      var offsetSize = new BMap.Size(-len / 2, -25);
      var label = new BMap.Label(content + spanA, {
        offset: offsetSize,
      });
      label.setStyle(labelStyle);
      return label;
    },
    toPoint(point) {
      // 百度地图API功能
      let map = this.map;
      map.panTo(point);
    },

    getCurrentPosition() {
      let that = this;
      // 百度地图API功能
      let map = this.map;
      let BMap = window.BMap;
      let geolocation = new BMap.Geolocation();

      that.currentValue = "";
      that.placeholder = "定位中";
      geolocation.getCurrentPosition(
        function (r) {
          if (this.getStatus() == BMAP_STATUS_SUCCESS) {
            that.myPoint = r.point;
            that.markPoint(r.point, "当前", true);
            that.markLine([r.point, that.companyPoint]);
            that.mark++;
            if (that.frequency > 0) {
              setTimeout(() => {
                that.getCurrentPosition();
              }, that.frequency);
            }
          } else {
            that.$toast("failed" + this.getStatus());
          }
        },
        { enableHighAccuracy: true }
      );

      //关于状态码
      //BMAP_STATUS_SUCCESS 检索成功。对应数值“0”。
      //BMAP_STATUS_CITY_LIST 城市列表。对应数值“1”。
      //BMAP_STATUS_UNKNOWN_LOCATION  位置结果未知。对应数值“2”。
      //BMAP_STATUS_UNKNOWN_ROUTE 导航结果未知。对应数值“3”。
      //BMAP_STATUS_INVALID_KEY 非法密钥。对应数值“4”。
      //BMAP_STATUS_INVALID_REQUEST 非法请求。对应数值“5”。
      //BMAP_STATUS_PERMISSION_DENIED 没有权限。对应数值“6”。(自 1.1 新增)
      //BMAP_STATUS_SERVICE_UNAVAILABLE 服务不可用。对应数值“7”。(自 1.1 新增)
      //BMAP_STATUS_TIMEOUT 超时。对应数值“8”。(自 1.1 新增)
    },
  },
};
</script>
<style lang="less" scoped>
.tips {
  text-align: center;
  font-size: 10px;
  color: #333;
}
.sign-btn-box {
  width: 2rem;
  height: 2rem;
  margin: 0.5rem auto;
  background: yellowgreen;
      background-image: radial-gradient(circle, yellowgreen, rgb(156, 206, 57), rgb(98, 131, 33));
  border-radius: 50%;
  .sign-btn-title {
    font-size: 0.5rem;
    font-weight: bold;
    color: white;
  }
  .small {
    font-size: 0.25rem;
  }
  .sign-btn-time {
    font-size: 0.3rem;
    color: white;
  }
}
.sign-btn-box.not-ready {
  background: red;
  background-image: radial-gradient(circle, red, #f43030, #7d4242);  
}
</style>

vuejs前端vchart.js百度地图电子围栏手机定位手机打卡

上一篇:VUE 前端zxing-js生成二维码DEMO

下一篇:MySQL数据库保存Emoji表情

本文链接: http://www.nanshanqiao.com/zz_article/62.html

暂无评论