鸿蒙ArtTS 中如何实现地图打卡功能 比如公司打卡 文章配置完整代码

一、首先要拿到自己的定位信息

csharp 复制代码
this.location = await geoLocationManager.getCurrentLocation()
  • 打开权限,一行代码拿到定位信息,核心API是geoLocationManager
  • 这里的经纬度是我们判断是否可以打卡成功的关键。

二、画地图(华为地图)

  • 拿到公司的经纬度信息进行Marker标记,进行相关配置
  • 然后在公司的经纬度上进行Circle画圆,进行相关配置(假设半径为500)
kotlin 复制代码
import { MapComponent, mapCommon, map } from '@kit.MapKit';
import { AsyncCallback } from '@kit.BasicServicesKit';
import { abilityAccessCtrl, Permissions } from '@kit.AbilityKit';
import { geoLocationManager } from '@kit.LocationKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
struct HuaweiMapDemo {
  @State location:geoLocationManager.Location | null = null
  @State b:number = 0
  private TAG = "HuaweiMapDemo";
  private mapOptions?: mapCommon.MapOptions;
  private callback?: AsyncCallback<map.MapComponentController>;
  private mapController?: map.MapComponentController;
  private mapEventManager?: map.MapEventManager;
  private marker?: map.Marker;
  private mapCircle?: map.MapCircle;

  async aboutToAppear(){
    this.requestPermissions(["ohos.permission.LOCATION","ohos.permission.APPROXIMATELY_LOCATION"])
    // 地图初始化参数,设置地图中心点坐标及层级
    this.mapOptions = {
      position: {
        target: {
          latitude: 22.19,
          longitude: 114.11
        },
        zoom: 10
      },
      myLocationControlsEnabled: true,
      alwaysShowScaleEnabled:true
    };

    // 地图初始化的回调
    this.callback = async (err, mapController) => {
      if (!err) {
        // 获取地图的控制器类,用来操作地图
        this.mapController = mapController;
        let location = await geoLocationManager.getCurrentLocation();
        this.mapController.setMyLocation(location);
        // 启用我的位置图层
        this.mapController.setMyLocationEnabled(true);
        // 启用我的位置按钮
        this.mapController.setMyLocationControlsEnabled(true);
        // let style: mapCommon.MyLocationStyle = {
        //   anchorU: 0.5,
        //   anchorV: 0.5,
        //   radiusFillColor: 0xffff0000,
        //   // icon为自定义图标资源,使用时需要替换
        //   // 图标存放在resources/rawfile,icon参数传入rawfile文件夹下的相对路径
        //   icon: 'images/logo.png'
        // };
        // await this.mapController.setMyLocationStyle(style);

        this.mapEventManager = this.mapController.getEventManager();
        //this.mapEventManager.on("myLocationButtonClick", callback);
        // Marker初始化参数
        let markerOptions: mapCommon.MarkerOptions = {
          position: {
            latitude: 22.64,
            longitude: 113.92
          },
          rotation: 0,
          visible: true,
          zIndex: 0,
          alpha: 1,
          anchorU: 0.5,
          anchorV: 1,
          clickable: true,
          draggable: true,
          flat: false,
          // 图标存放在resources/rawfile,icon参数传入rawfile文件夹下的相对路径
          icon: 'images/head.png'
        };
        // 创建Marker
        this.marker = await this.mapController.addMarker(markerOptions);
        // 设置信息窗的标题
        this.marker.setTitle('深圳');
        // 设置信息窗的子标题
        this.marker.setSnippet('小黑程序员');
        // 设置标记可点击
        this.marker.setClickable(true);
        // 设置信息窗的锚点位置
        this.marker.setInfoWindowAnchor(1, 1);
        // 设置信息窗可见
        this.marker.setInfoWindowVisible(true);
        // 地图加载完成事件
        let callback = () => {
          console.info(this.TAG, `on-mapLoad`);
        }
        this.mapEventManager.on("mapLoad", callback);
        let mapCircleOptions: mapCommon.MapCircleOptions = {
          center: {
            latitude: 22.64,
            longitude: 113.92
          },
          radius: 564,
          clickable: true,
          fillColor: 0XFFFFC100,
          strokeColor: 0xFFFF0000,
          strokeWidth: 10,
          visible: true,
          zIndex: 15
        }
        this.mapCircle = await this.mapController.addCircle(mapCircleOptions);
      }
    };
    // let markerOptions:mapCommon.MarkerOptions = {
    //   position:{latitude:39.9,longitude:116.4}
    // }
    // let marker:map.Marker = await this.mapController?.addMarker(markerOptions)
    // marker.
  }
  async requestPermissions(permissions:Permissions[]){
    const atManager = abilityAccessCtrl.createAtManager()
    const requestResult = await atManager.requestPermissionsFromUser(getContext(),permissions)
    const isAuth=requestResult.authResults.every(item=>item===abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED)
    return isAuth === true ? Promise.resolve(true) : Promise.reject(false)
  }

  // 页面每次显示时触发一次,包括路由过程、应用进入前台等场景,仅@Entry装饰的自定义组件生效
  onPageShow(): void {
    // 将地图切换到前台
    if (this.mapController) {
      this.mapController.show();
    }
  }

  // 页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅@Entry装饰的自定义组件生效
  onPageHide(): void {
    // 将地图切换到后台
    if (this.mapController) {
      this.mapController.hide();
    }
  }

  build() {
    Stack({ alignContent: Alignment.Center }) {
      Text(this.b+'当前的位置信息:'+JSON.stringify(this.location,null,2))
        .position({ x: 0, y: 0 })
        .zIndex(99)
      Button('打卡')
        .zIndex(99)
        .position({ x: 20, y: 20 }) // 调整按钮位置
        .onClick(async()=>{
          let fromLatLng: mapCommon.LatLng = {
            latitude: 22.64,
            longitude: 113.92
          };
          this.location = await geoLocationManager.getCurrentLocation()
          const toLatLng: mapCommon.LatLng = {
            latitude: this.location.latitude,
            longitude: this.location.longitude
          }
          let distance = map.calculateDistance(fromLatLng, toLatLng);
          this.b = distance
          if(564 > distance){
            promptAction.showToast({message:'打卡成功'})
            //发送服务器
          }else{
            promptAction.showToast({message:'打卡失败'})
          }
        })
      // 调用MapComponent组件初始化地图
      MapComponent({ mapOptions: this.mapOptions, mapCallback: this.callback }).width('100%').height('100%');
    }.height('100%').width('100%')

  }
}

三、点击按钮判断是否可以打卡成功

四、或者先判断是否可以打卡成功来显示对应的按钮状态

这个逻辑是一样的

注:使用CalculateDistance获得的距离和你用Circle画的圆可能会有出入

相关推荐
1024小神19 分钟前
vue3 项目配置多语言支持,如何从服务端拿多语言配置
前端·javascript·vue.js
NoneCoder19 分钟前
Symbol、Set 与 Map:新数据结构探秘
前端·javascript·数据结构
ichterry1 小时前
chrome打不开axure设计的软件产品原型问题解决办法
前端·chrome·axure
归于尽1 小时前
从0开始学习的防抖与节流
前端·javascript
Mintopia1 小时前
Three.js 自定义着色器(Custom Shaders)
前端·javascript·three.js
时光足迹1 小时前
电子书阅读器之笔记高亮
前端·javascript·react.js
洛小豆1 小时前
我问她:WebSocket 怎么发大文本,她说:豆子,别一口气塞下去,会噎到的
前端·javascript·websocket
萌萌哒草头将军1 小时前
苏醒吧,Remix!好消息,Remix将基于Preact 重构,更快更轻量!🚀🚀🚀
前端·vue.js·react.js
姑苏洛言1 小时前
在线考试系统的设计与实现
前端·后端
江城开朗的豌豆1 小时前
JavaScript篇:突破单线程束缚!前端也能玩转多线程的奇妙之旅
前端·javascript·面试