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.pswp.cn/diannao/82586.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82586.shtml
英文地址,請注明出處:http://en.pswp.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…