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 开发中取得更好的成果!
HarmonyOS运动开发:如何集成百度地图SDK、运动跟随与运动公里数记录的更多相关文章
- Android Studio 项目中集成百度地图SDK报Native method not found: com.baidu.platform.comjni.map.commonmemcache.JNICommonMemCache.Create:()I错误
Android Studio 项目中集成百度地图SDK报以下错误: java.lang.UnsatisfiedLinkError: Native method not found: com.baidu ...
- Android Studio集成百度地图SDK
1.建议先阅读百度地图官方的继承指南,针对了Eclipse和Android Studio. 百度官方集成指南 2.下载百度地图SDK Android SDK v4.1.1 下载有两种: 1.一键下载( ...
- Xamarin.Android 集成百度地图SDK
前言:趁着周六闲得没事干,赶紧搞一搞Xamarin,最近也是怪无聊的,枯燥的生活不如打几行代码带劲:好了我们进入正题 我这篇文章时参考一位大佬的博客进行改变的,当然他写的需要一定的经验才可以看得懂,我 ...
- Android 开发之集成百度地图的定位与地图展示
app 应用中,大多数应用都具有定位功能,百度定位就成了开发人员的集成定位功能的首选,近期也在做定位功能,可是发现百度真是个大坑啊, sdk 命名更新了,相关代码却不更新,害得我花费了非常长时间来研究 ...
- iOS开发之集成百度地图踩过的那些坑(基于 Xcode7.0/iOS9.2)
本篇分4步讲述如何在项目中集成百度地图: 第一步:创建项目 第二步:利用 cocoaPod 导入百度地图的 SDK(pod 'BaiduMapKit' #百度地图SDK) 第三步:在 pch 文件中导 ...
- iOS开发之引用百度地图SDK(一)-----------SDK开发指南
(void)viewWillAppear:(BOOL)animated { [_mapView viewWillAppear]; _mapView.delegate = self; // 此处记得不用 ...
- Android集成百度地图SDK
本Demo中所含功能 1:定位,显示当前位置 2:地图多覆盖物(地图描点.弹出该点的具体信息) 3:坐标地址互相换算 4:POI兴趣点检索 5:线路查询(步行,驾车,公交) 6:绘制线路(OpenGL ...
- iOS开发---集成百度地图完善版
一.成为百度的开发者.创建应用 http://developer.baidu.com/map/index.php?title=首页 (鼠标移向 然后选择你的项目需要的功能 你可以在里面了解到你想要使用 ...
- iOS开发---集成百度地图
由于iOS MapKit框架很多情况并不能满足我们的需求,我们可以选择集成百度地图,那该如何操作呢? 申请Key 登录百度API管理中心申请Key http://lbsyun.baidu.com/ap ...
- iOS百度地图SDK集成详细步骤
1.iOS百度地图下载地址 http://developer.baidu.com/map/index.php?title=iossdk/sdkiosdev-download 根据需要选择不同的版本 ...
随机推荐
- 《Vue2 框架第二课:组件结构与模板语法详解》
写在开头:Vue.js 是一个流行的前端框架,广泛应用于构建用户界面和单页应用(SPA).然而,需要注意的是,Vue2 已经于 2023 年底 正式停止维护.这意味着官方团队将不再为 Vue2 提供功 ...
- [SDOI2008] 洞穴勘测 题解
似乎所有的线段树分治题都能被 \(LCT\) 平替掉? 一眼动态树,直接 \(LCT\). Connect x y 操作用 \(link(x,y)\) 实现,Destroy x y 操作用 \(cut ...
- DeepSeek “源神”启动!「GitHub 热点速览」
上周,DeepSeek 官方宣布将陆续发布 5 个开源项目.本周一开源社区就迎来了首发之作--FlashMLA!该项目开源后,不到一天 Star 数已突破 6k,并且还在以惊人的速度持续飙升. Gi ...
- MIT 操作系统6.S081第一章
1.1进程和内存 fork 父进程中 fork 返回 子进程的PID 子进程中 fork 返回 0 exit exit会让当前进程停止执行并释放资源(包括内存和打开的文件) 通常: 0 表示 成功 1 ...
- 如何调用CMD实现多个同类文件合并的研究 · 二进制 · 依次 · 文本图像视频音频
引言 视频网站内,使用视频下载嗅探器下载了视频,打开资源管理器一看,是几千个.ts文件,见下图: 通过播放部分视频,发现其实内容是完整的,只是自动切割了多份,倘若无缝拼接为一个完整视频单元,就可以 ...
- [tldr]GO使用正则表达式
简述如何使用GO调用正则表达式 是否符合条件 使用MatchString方法实现 _, err := regexp.MatchString(regex, str) 提取内容 Compile 第一步需要 ...
- laravel The Process class relies on proc_open, which is not available on your PHP installation.
解决办法: 在php.ini中,找到disable_functions选项,看看后面是否有proc_open函数被禁用了,去掉proc_get_status,proc_open即可
- Java SE 24 新增特性
Java SE 24 新增特性 作者:Grey 原文地址: 博客园:Java SE 24 新增特性 CSDN:Java SE 24 新增特性 源码 源仓库: Github:java_new_featu ...
- 【Pandas】concat方法使用注意点
使用pandas库的concat做数据拼接需要注意,应该先对原始数据设置列名,如果没有设置列名,在拼接时只会保留第一个文件的第一行(以列名形式),由于剩下的文件在读取时会自动将第一行作为列名,这样就会 ...
- DeepSeek 官方推出的实用集成工具百宝箱,建议收藏!
项目介绍 该实用集成工具百宝箱汇聚了DeepSeek官方精心挑选和推荐的各类集成工具(其中包括:应用程序.AI Agent 框架.AI数据应用框架.RAG 框架.浏览器插件.VS Code 插件等), ...