免费的 H5/PC 地图打卡功能实现 —— 功能代码已上传

263 阅读3分钟

地图打卡  

让我们一起探索如何使用天地图实现打卡功能!

🛠️ 准备工作

地图平台: 天地图  

优势: 免费、便捷  

网址: 天地图 API

步骤 1:申请 API Key

首先,你需要前往天地图官网申请一个 API Key,之后我们将使用该 key 来加载地图资源。  

提示: API Key 是访问天地图服务的凭证,请妥善保存。

步骤 2:加载外部资源

申请好 API Key 后,按照下面的步骤引入天地图的脚本资源。


<script src="https://api.tianditu.gov.cn/api?v=4.0&tk=你的key值"></script>

💻 代码实现

📋 模板代码

以下是地图打卡功能的完整代码。您只需将以下代码复制到项目中,并替换 API Key

即可使用。

1. HTML 结构 我们将地图展示在页面的 div中,并在页面底部加入打卡按钮:


<template>

  <view>

    <!-- 地图展示区域 -->

    <div id="mapDiv" style="position: absolute; width: 100%; height: 93%"></div>

  


    <!-- 打卡按钮 -->

    <div class="dkBtn" @click="test">打卡</div>

  </view>

</template>

2. JavaScript 逻辑 在 mounted 生命周期中加载地图,并每隔 1秒获取用户的地理位置进行打卡距离的计算。


<script>

  import proj4 from "proj4"; // 引入坐标转换库

  


  export default {

    name: "MapComponent",

    data() {

      return {

        map: null,

        zoom: 17,

        timer: null,

        user: {

          userLng: null,

          userLat: null,

        },

        userMarker: null, // 用户位置的标记

      };

    },

    mounted() {

      this.loadScript()

        .then(() => {

          this.initMap();

  


          // 定时获取用户位置

          this.timer = setInterval(() => {

            this.getLocation();

          }, 1000);

        })

        .catch((error) => {

          console.error("加载天地图脚本失败:", error);

        });

    },

    beforeDestroy() {

      clearInterval(this.timer);

    },

    methods: {

      // 打卡功能

      test() {

        const userPosition = new T.LngLat(this.user.userLng, this.user.userLat);

        const centerPoint = new T.LngLat(117.0953, 31.833); // 打卡点坐标

        const distance = this.map.getDistance(centerPoint, userPosition); // 计算用户和打卡点的距离

  


        // 判断距离是否在200米以内

        if (distance <= 200) {

          uni.showToast({

            title: "打卡成功",

          });

          console.log("打卡成功");

        } else {

          uni.showToast({

            title: "未在打卡范围内",

          });

          console.log("未在打卡范围内");

        }

      },

  


      // 获取用户位置

      getLocation() {

        if (navigator.geolocation) {

          navigator.geolocation.getCurrentPosition(

            (position) => {

              // 获取 WGS84 坐标

              const userLng = position.coords.longitude;

              const userLat = position.coords.latitude;

  


              // 坐标转换为 CGCS2000

              const cgcs2000Coordinates = proj4(WGS84, CGCS2000, [

                userLng,

                userLat,

              ]);

              this.user.userLng = cgcs2000Coordinates[0];

              this.user.userLat = cgcs2000Coordinates[1];

  


              // 更新地图上的用户标记

              const centerPoint = new T.LngLat(

                this.user.userLng,

                this.user.userLat

              );

              if (this.userMarker) {

                this.map.removeOverLay(this.userMarker);

              }

              this.userMarker = new T.Marker(centerPoint);

              this.map.addOverLay(this.userMarker);

            },

            (error) => {

              console.error("获取位置失败:", error);

            }

          );

        } else {

          console.log("浏览器不支持获取地理位置");

        }

      },

  


      // 加载天地图脚本

      loadScript() {

        return new Promise((resolve, reject) => {

          const script = document.createElement("script");

          script.src = "https://api.tianditu.gov.cn/api?v=4.0&tk=你的key值";

          script.onload = resolve;

          script.onerror = reject;

          document.head.appendChild(script);

        });

      },

  


      // 初始化地图

      initMap() {

        this.map = new T.Map("mapDiv");

        const centerPoint = new T.LngLat(117.0953, 31.833); // 中心点

        this.map.centerAndZoom(centerPoint, this.zoom);

        this.map.enableScrollWheelZoom();

        this.addMarkerWithLabel(centerPoint, "中安创谷"); // 添加目标点

      },

  


      // 添加标记及文本信息

      addMarkerWithLabel(position, text) {

        const marker = new T.Marker(position); // 添加标记

        this.map.addOverLay(marker);

        const label = new T.Label({

          text: text,

          position: position,

          offset: new T.Point(15, -30),

        });

        this.map.addOverLay(label);

  


        // 添加打卡范围圆形

        const circle = new T.Circle(position, 200, {

          color: "blue",

          weight: 2,

          opacity: 0.5,

          fillColor: "orange",

          fillOpacity: 0.5,

        });

        this.map.addOverLay(circle);

      },

    },

  };

</script>

3. 样式美化 为了让打卡按钮更加显眼,我们可以通过 CSS 进行简单的样式调整:


<style scoped>

  * {

    padding: 0;

    margin: 0;

    box-sizing: border-box;

  }

  


  .dkBtn {

    position: absolute;

    bottom: 0;

    display: flex;

    justify-content: center;

    align-items: center;

    cursor: pointer;

    width: 100%;

    height: 7%;

    color: #fff;

    font-size: 20px;

    text-align: center;

    background-color: #007aff;

  }

</style>

🚀 完成 到这里,我们已经完成了地图打卡功能的开发。通过天地图API,我们可以在地图上展示用户位置,并根据预设的打卡点和距离限制,实现精确的打卡功能。

🚀 github项目地址:github.com/dashen-lvwe…

🔗 参考链接 天地图 API 官网 Proj4js 坐标转换库