HarmonyOS运动开发:如何集成百度地图SDK、运动跟随与运动公里数记录

前言

在开发运动类应用时,集成地图功能以及实时记录运动轨迹和公里数是核心需求之一。本文将详细介绍如何在 HarmonyOS 应用中集成百度地图 SDK,实现运动跟随以及运动公里数的记录。

一、集成百度地图 SDK

1.引入依赖

首先,需要在项目的文件中引入百度地图相关的依赖包:

"dependencies": {"@bdmap/base": "1.2.6","@bdmap/search": "1.2.6","@bdmap/map": "1.2.6","@bdmap/locsdk": "1.1.4"
}

2.初始化百度地图

为了使用百度地图的功能,我们需要进行初始化操作。这包括设置 API Key 和初始化定位客户端。

MapUtil 类


export class MapUtil{public static initialize(context:Context){Initializer.getInstance().initialize("你的key");// 设置是否同意隐私合规政策接口// true,表示同意隐私合规政策// false,表示不同意隐私合规政策LocationClient.checkAuthKey("你的key", (result: string) => {console.debug("result = " + result); // 可打印出是否鉴权成功的结果});LocationClient.setAgreePrivacy(true);LocManager.getInstance().init(context);}}

LocManager 类


export class LocManager {private client: LocationClient | null = null;private static instance: LocManager;public static getInstance(): LocManager {if (!LocManager.instance) {LocManager.instance = new LocManager();}return LocManager.instance;}constructor() {}init(context: Context) {if (this.client == null) {try {this.client = new LocationClient(context);} catch (error) {console.error("harmony_baidu_location error: " + error.message);}}if (this.client != null) {this.client.setLocOption(this.getDefaultLocationOption());}}start() {if (this.client != null) {this.client.start();}}stop() {if (this.client != null) {this.client.stop();}}requestSingleLocation() {if (this.client != null) {this.client.requestSingleLocation();}}registerListener(listener: BDLocationListener): boolean {let isSuccess: boolean = false;if (this.client != null && listener != null) {this.client.registerLocationListener(listener);isSuccess = true;}return isSuccess;}unRegisterListener(listener: BDLocationListener) {if (this.client != null && listener != null) {this.client.unRegisterLocationListener(listener);}}getSDKVersion(): string {let version: string = "";if (this.client != null) {version = this.client.getVersion();}return version;}enableLocInBackground(wantAgent: WantAgent) {if (this.client != null) {this.client.enableLocInBackground(wantAgent);}}disableLocInBackground() {if (this.client != null) {this.client.disableLocInBackground();}}getDefaultLocationOption() {let option = new LocationClientOption();option.setCoorType("bd09ll"); // 可选,默认为gcj02,设置返回的定位结果坐标系option.setTimeInterval(3); // 可选,默认1秒,设置连续定位请求的时间间隔option.setDistanceInterval(0); // 可选,默认0米,设置连续定位的距离间隔option.setIsNeedAddress(true); // 可选,设置是否需要地址信息,默认不需要option.setIsNeedLocationDescribe(true); // 可选,默认为false,设置是否需要地址描述option.setIsNeedLocationPoiList(true); // 可选,默认能为false,设置是否需要POI结果option.setLocationMode(LocationMode.High_Accuracy); // 可选,默认高精度,设置定位模式,高精度、低功耗、仅设备option.setSingleLocatingTimeout(3000); // 可选,仅针对单次定位生效,设置单次定位的超时时间return option;}}

3.定位监听器

为了处理定位数据,我们需要实现一个定位监听器:


export class MapLocationListener extends BDLocationListener {private callback: (location: BDLocation) => void;constructor(callback: (location: BDLocation) => void) {super();this.callback = callback;}onReceiveLocation(bdLocation: BDLocation): void {this.callback(bdLocation);}
}

二、页面使用

1.权限申请

在文件中声明所需的权限:

"requestPermissions": [{"name": "ohos.permission.LOCATION","reason": "$string:location_permission","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}},{"name": "ohos.permission.LOCATION_IN_BACKGROUND","reason": "$string:background_location_permission","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}},{"name": "ohos.permission.APPROXIMATELY_LOCATION","reason": "$string:fuzzy_location_permission","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}},{"name": "ohos.permission.APP_TRACKING_CONSENT","reason": "$string:get_oaid_permission","usedScene": {"abilities": ["EntryAbility"],"when": "inuse"}},{"name": "ohos.permission.KEEP_BACKGROUND_RUNNING","reason": "$string:keep_background_running_permission","usedScene": {"abilities": ["EntryAbility1"],"when": "inuse"}}]

2.请求权限

在页面中请求权限:

private async requestPermissions(): Promise<boolean> {const permissions : Permissions[]= ['ohos.permission.LOCATION','ohos.permission.APPROXIMATELY_LOCATION','ohos.permission.APP_TRACKING_CONSENT',]return LibPermission.requestPermissions(permissions)}

3.页面调用

方向感应

使用鸿蒙系统自带的方向传感器来获取设备的朝向角度:

// 初始化方向传感器sensor.on(sensor.SensorId.ORIENTATION, (data) => {// 获取设备朝向角度(绕Z轴旋转角度)this.currentRotation = data.alpha;if(this.loc){this.loc.location = new LatLng(this.currentLatitude, this.currentLongitude);this.loc.direction = this.currentRotation;this.loc.radius = 0;}});// 用完记得取消监听
sensor.off(sensor.SensorId.ORIENTATION);

编写定位监听器

private mListener: MapLocationListener = new MapLocationListener((bdLocation: BDLocation) => {this.currentLatitude = bdLocation.getLatitude();this.currentLongitude = bdLocation.getLongitude();this.currentRadius = bdLocation.getRadius();// 更新地图位置和位置标记if (this.mapController) {// 更新地图中心点this.mapController.setMapCenter({lat: this.currentLatitude,lng: this.currentLongitude},15);if(this.loc){// 设置定位图标位置、指向以及范围this.loc.location = new LatLng(this.currentLatitude, this.currentLongitude);this.loc.direction = this.currentRotation;// 单位米this.loc.radius = 0;}}});

启动和关闭定位

// 启动定位
LocManager.getInstance().registerListener(this.mListener);
LocManager.getInstance().start();// 关闭定位
LocManager.getInstance().unRegisterListener(this.mListener);
LocManager.getInstance().stop();

百度地图集成

在页面中集成百度地图:

MapComponent({ onReady: async (err, mapController:MapController) => {if (!err) {// 获取地图的控制器类,用来操作地图this.mapController= mapController;let result = this.mapController.getLayerByTag(SysEnum.LayerTag.LOCATION);if(result){this.loc = result as LocationLayer;}if(this.currentLatitude!=0&&this.currentLongitude!=0){if(this.loc){// 设置定位图标位置、指向以及范围this.loc.location = new LatLng(this.currentLatitude, this.currentLongitude);this.loc.direction = this.currentRotation;// 单位米this.loc.radius = 0;}this.mapController.setMapCenter({lat: this.currentLatitude,lng: this.currentLongitude},15);}}}, mapOptions: this.mapOpt }).width('100%').height('100%')

三、公里数计算

在运动应用中,记录用户的运动轨迹并计算运动的总距离是核心功能之一。为了实现这一功能,我们需要设计一个数据模型来记录运动轨迹点,并通过这些点计算总距离。

1.运动轨迹点模型

定义一个RunPoint类来表示运动轨迹中的一个点,包含纬度、经度和时间戳:

/*** 运动轨迹点数据模型*/
export class RunPoint {// 纬度latitude: number;// 经度longitude: number;// 时间戳timestamp: number;// 所属公里数分组(第几公里)kilometerGroup: number;constructor(latitude: number, longitude: number) {this.latitude = latitude;this.longitude = longitude;this.timestamp = Date.now();this.kilometerGroup = 0; // 默认分组为0}
}

2.运动轨迹管理类

创建一个RunTracker类来管理运动轨迹点,并计算总距离:


/*** 运动轨迹管理类*/
export class RunTracker {// 所有轨迹点private points: RunPoint[] = [];// 当前总距离(公里)private totalDistance: number = 0;// 当前公里数分组private currentKilometerGroup: number = 0;/*** 添加新的轨迹点* @param latitude 纬度* @param longitude 经度* @returns 当前总距离(公里)*/addPoint(latitude: number, longitude: number): number {const point = new RunPoint(latitude, longitude);if (this.points.length > 0) {// 计算与上一个点的距离const lastPoint = this.points[this.points.length - 1];const distance = this.calculateDistance(lastPoint, point);this.totalDistance += distance;// 更新公里数分组point.kilometerGroup = Math.floor(this.totalDistance);if (point.kilometerGroup > this.currentKilometerGroup) {this.currentKilometerGroup = point.kilometerGroup;}}this.points.push(point);return this.totalDistance;}/*** 计算两点之间的距离(公里)* 使用Haversine公式计算球面距离*/private calculateDistance(point1: RunPoint, point2: RunPoint): number {const R = 6371; // 地球半径(公里)const lat1 = this.toRadians(point1.latitude);const lat2 = this.toRadians(point2.latitude);const deltaLat = this.toRadians(point2.latitude - point1.latitude);const deltaLon = this.toRadians(point2.longitude - point1.longitude);const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +Math.cos(lat1) * Math.cos(lat2) *Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));return R * c;}/*** 将角度转换为弧度*/private toRadians(degrees: number): number {return degrees * (Math.PI / 180);}/*** 获取当前总距离*/getTotalDistance(): number {return this.totalDistance;}/*** 获取指定公里数分组的轨迹点*/getPointsByKilometer(kilometer: number): RunPoint[] {return this.points.filter(point => point.kilometerGroup === kilometer);}/*** 清空轨迹数据*/clear(): void {this.points = [];this.totalDistance = 0;this.currentKilometerGroup = 0;}
}

3.页面的监听器里记录公里数

在页面中使用RunTracker类来记录运动轨迹点并计算总距离:

  private runTracker: RunTracker = new RunTracker();
监听器添加代码const distance = this.runTracker.addPoint(this.currentLatitude, this.currentLongitude);distance就是当前运动的公里数

四、总结

本文详细介绍了如何在 HarmonyOS 应用中集成百度地图 SDK,实现运动跟随以及运动公里数的记录。通过以下步骤,我们可以实现一个功能完整的运动应用:

• 集成百度地图 SDK:

• 引入必要的依赖包。

• 初始化百度地图并设置定位选项。

• 页面使用:

• 请求必要的权限。

• 启动和关闭定位。

• 实时更新地图位置和方向。

• 公里数计算:

• 定义运动轨迹点模型。

• 使用 Haversine 公式计算两点之间的距离。

• 记录运动轨迹点并实时更新总距离。

通过这些步骤,开发者可以轻松实现一个功能强大的运动应用,为用户提供实时的运动数据和地图跟随功能。希望本文的内容能够帮助你在 HarmonyOS 开发中取得更好的成果!

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

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

相关文章

如何理解k8s中的controller

一、基本概念 在k8s中&#xff0c;Controller&#xff08;控制器&#xff09;是核心组件之一&#xff0c;其负责维护集群状态并确保集群内的实际状态与期望状态一致的一类组件。控制器通过观察集群的当前状态并将其与用户定义的期望状态进行对比&#xff0c;做出相应的调整来实…

《Go小技巧易错点100例》第三十二篇

本期分享&#xff1a; 1.sync.Map的原理和使用方式 2.实现有序的Map sync.Map的原理和使用方式 sync.Map的底层结构是通过读写分离和无锁读设计实现高并发安全&#xff1a; 1&#xff09;双存储结构&#xff1a; 包含原子化的 read&#xff08;只读缓存&#xff0c;无锁快…

【MySQL】行结构详解:InnoDb支持格式、如何存储、头信息区域、Null列表、变长字段以及与其他格式的对比

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…

LabVIEW多通道并行数据存储系统

在工业自动化监测、航空航天测试、生物医学信号采集等领域&#xff0c;常常需要对多个传感器通道的数据进行同步采集&#xff0c;并根据后续分析需求以不同采样率保存特定通道组合。传统单线程数据存储方案难以满足实时性和资源利用效率的要求&#xff0c;因此设计一个高效的多…

【Linux系列】bash_profile 与 zshrc 的编辑与加载

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

针对Mkdocs部署到Githubpages加速访问速度的一些心得

加速网站访问的一些心得 在使用 MkDocs 构建网站时&#xff0c;为了提高访问速度&#xff0c;我们可以采取以下一些措施&#xff1a; 1. 优化图片 使用合适的图片格式&#xff0c;如 WebP、JPEG2000 等&#xff0c;减少图片文件大小&#xff0c;从而加快加载速度。 可以使用…

Mysql中切割字符串作为in的查询条件

问题&#xff1a;需要将一个字符串切割成数组作为in的查询条件&#xff0c;如&#xff1a; select * from table_1 where name in (select slit(names) from table_2 where id 3); names 返回的格式是’name1,name2,name3…,需要将name按照逗号切割作为in的查询条件&#xff1b…

云计算中的虚拟化:成本节省、可扩展性与灾难恢复的完美结合

云计算中虚拟化的 4 大优势 1. 成本效益 从本质上讲&#xff0c;虚拟化最大限度地减少了硬件蔓延。团队可以将多个虚拟机整合到单个物理主机上&#xff0c;而不是为每个工作负载部署单独的服务器。这大大减少了前期硬件投资和持续维护。 结果如何&#xff1f;更低的功耗、更低…

Linux : 多线程【线程概念】

Linux &#xff1a; 多线程【线程概念】 &#xff08;一&#xff09;线程概念线程是什么用户层的线程linux中PID与LWP的关系 (二) 进程地址空间页表(三) 线程总结线程的优点线程的缺点线程异常线程用途 &#xff08;一&#xff09;线程概念 线程是什么 在一个程序里的一个执行…

IDEA转战TREA AI IDE : springboot+maven+vue项目配置

一、trea下载安装 Trae官方网址&#xff1a; https://www.trae.com.cn/ Trae官方文档&#xff1a;https://docs.trae.com.cn/docs/what-is-trae?_langzh w3cschool&#xff1a; https://www.w3cschool.cn/traedocs/ai-settings.html 安装这里省略&#xff0c;正常安装即可。…

Java--图书管理系统(简易版)

目录 目录 前言 &#x1f514;1.library包 1.1 Book类 1.2 BookList类 &#x1f514;2.user包 2.1User类(父类) 2.2Admin(管理员) 2.3 NormalUser(普通用户) &#x1f514;3.Operation包 &#x1f550;3.1 IOperation接口 &#x1f551;3.2ListOperation(查看操作)…

深入浅出:Spring Boot 中 RestTemplate 的完整使用指南

在分布式系统开发中&#xff0c;服务间通信是常见需求。作为 Spring 框架的重要组件&#xff0c;RestTemplate 为开发者提供了简洁优雅的 HTTP 客户端解决方案。本文将从零开始讲解 RestTemplate 的核心用法&#xff0c;并附赠真实地图 API 对接案例。 一、环境准备 在 Spring…

大数据处理利器:Hadoop 入门指南

一、Hadoop 是什么&#xff1f;—— 分布式计算的基石 在大数据时代&#xff0c;处理海量数据需要强大的技术支撑&#xff0c;Hadoop 应运而生。Apache Hadoop 是一个开源的分布式计算框架&#xff0c;致力于为大规模数据集提供可靠、可扩展的分布式处理能力。其核心设计理念是…

685SJBH计量管理系统

摘 要 计量&#xff0c;在我国已有五千年的历史。计量的发展与社会进步联系在一起&#xff0c;它是人类文明的重要组成部分。它的发展经历了古典阶段、经典阶段和现代阶段。而企业的计量管理是对测量数据、测量过程和测量设备的管理。 本系统通过分析现有计量系统的业务逻辑…

从0到1构建前端监控系统:错误捕获、性能采集、用户体验全链路追踪实战指南SDK实现

目录 前言为什么要做前端监控前端监控目标稳定性用户体验业务 前端监控流程常见埋点方案代码埋点可视化埋点无痕埋点 创建项目第一步、创建monitor文件&#xff0c;cmd进入文件进行npm init -y 项目初始化第二步、创建src/index.js和src/index.html文件第三步、创建webpack.con…

前端浏览器判断设备类型的方法

前端浏览器判断设备类型的方法 在前端开发中&#xff0c;判断设备类型&#xff08;如手机、平板、桌面电脑&#xff09;有多种方法&#xff0c;以下是常用的几种方式&#xff1a; 1. 使用 User Agent 检测 通过 navigator.userAgent 获取用户代理字符串进行判断&#xff1a;…

MNIST 手写数字分类

转自我的个人博客: https://shar-pen.github.io/2025/05/04/torch-distributed-series/1.MNIST/ 基础的单卡训练 本笔记本演示了训练一个卷积神经网络&#xff08;CNN&#xff09;来对 MNIST 数据集中的手写数字进行分类的过程。工作流程包括&#xff1a; 数据准备&#xff…

数据库中的 Segment、Extent、Page、Row 详解

在关系型数据库的底层存储架构中&#xff0c;数据并不是随意写入磁盘&#xff0c;而是按照一定的结构分层管理的。理解这些存储单位对于优化数据库性能、理解 SQL 执行过程以及排查性能问题都具有重要意义。 我将从宏观到微观&#xff0c;依次介绍数据库存储中的四个核心概念&…

DAMA车轮图

DAMA车轮图是国际数据管理协会&#xff08;DAMA International&#xff09;提出的数据管理知识体系&#xff08;DMBOK&#xff09;的图形化表示&#xff0c;它以车轮&#xff08;同心圆&#xff09;的形式展示了数据管理的核心领域及其相互关系。以下是基于用户提供的关键词对D…