鸿蒙NEXT开发定位工具类 (WGS-84坐标系)(ArkTs)

import geoLocationManager from '@ohos.geoLocationManager';
import { BusinessError, Callback } from '@ohos.base';
import { LogUtil } from './LogUtil';
import { PermissionUtil } from './PermissionUtil';
import { map, mapCommon } from '@kit.MapKit';
/*** 定位工具类 (WGS-84坐标系)* author: CSDN-鸿蒙布道师* since: 2025/04/22*/
export class LocationUtil {/*** 判断位置服务是否已经使能(定位是否开启)。* @returns true 表示定位已开启,false 表示未开启。*/static isLocationEnabled(): boolean {return geoLocationManager.isLocationEnabled();}/*** 申请定位权限。* @returns true 表示授权成功,false 表示用户拒绝授权。*/static async requestLocationPermissions(): Promise<boolean> {const permissions: Array<string> = ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'];let grant: boolean = await PermissionUtil.requestPermissions(permissions);if (!grant) {grant = await PermissionUtil.requestPermissionOnSetting(permissions);}return grant;}/*** 获取当前位置(简化版)。* @returns 当前位置信息。如果发生错误,则返回 null。*/static async getCurrentLocationEasy(): Promise<geoLocationManager.Location | null> {return LocationUtil.getCurrentLocation();}/*** 获取当前位置。* @param request 可选的定位请求参数。* @returns 当前位置信息。如果发生错误,则返回 null。*/static async getCurrentLocation(request?: geoLocationManager.CurrentLocationRequest | geoLocationManager.SingleLocationRequest): Promise<geoLocationManager.Location | null> {try {return await geoLocationManager.getCurrentLocation(request);} catch (err) {LocationUtil.handleError(err, '获取当前位置失败');return null; // 返回 null 表示发生错误}}/*** 开启位置变化订阅,并发起定位请求(简化版)。* @param callBack 回调函数。* @returns 成功返回 0,失败返回错误码。*/static onLocationChangeEasy(callBack: Callback<geoLocationManager.Location>): number {const defaultRequest: geoLocationManager.LocationRequest = {priority: geoLocationManager.LocationRequestPriority.FIRST_FIX,scenario: geoLocationManager.LocationRequestScenario.UNSET,timeInterval: 10,distanceInterval: 0,maxAccuracy: 0,};return LocationUtil.onLocationChange(defaultRequest, callBack);}/*** 开启位置变化订阅,并发起定位请求。* @param request 定位请求参数。* @param callBack 回调函数。* @returns 成功返回 0,失败返回错误码。*/static onLocationChange(request: geoLocationManager.LocationRequest | geoLocationManager.ContinuousLocationRequest,callBack: Callback<geoLocationManager.Location>): number {try {geoLocationManager.on('locationChange', request, callBack);return 0;} catch (err) {return LocationUtil.handleError(err, '开启位置变化订阅失败');}}/*** 关闭位置变化订阅,并删除对应的定位请求。* @param callback 不传则取消当前类型的所有订阅。* @returns 成功返回 0,失败返回错误码。*/static offLocationChange(callback?: Callback<geoLocationManager.Location>): number {try {if (callback) {geoLocationManager.off('locationChange', callback);} else {geoLocationManager.off('locationChange');}return 0;} catch (err) {return LocationUtil.handleError(err, '关闭位置变化订阅失败');}}/*** 判断地理编码与逆地理编码服务是否可用。* @returns true 表示服务可用,false 表示不可用。*/static isGeocoderAvailable(): boolean {return geoLocationManager.isGeocoderAvailable();}/*** 地理编码:将地理描述转换为具体坐标集合。* @param locationName 地理位置描述。* @param maxItems 返回结果的最大数量。* @returns 编码后的坐标集合。*/static async getGeoAddressFromLocationName(locationName: string,maxItems: number = 1): Promise<Array<geoLocationManager.GeoAddress>> {const geocodeRequest: geoLocationManager.GeoCodeRequest = {description: locationName,maxItems,locale: 'zh',};try {const result = await geoLocationManager.getAddressesFromLocationName(geocodeRequest);return result || [];} catch (err) {LocationUtil.handleError(err, '地理编码失败');return [];}}/*** 地理编码:将地理描述转换为具体坐标。* @param locationName 地理位置描述。* @returns 编码后的坐标对象。*/static async getAddressFromLocationName(locationName: string): Promise<geoLocationManager.GeoAddress> {const geoAddressList = await LocationUtil.getGeoAddressFromLocationName(locationName, 1);return geoAddressList.length > 0 ? geoAddressList[0] : {};}/*** 逆地理编码:将坐标转换为地理描述集合。* @param latitude 纬度。* @param longitude 经度。* @param maxItems 返回结果的最大数量。* @returns 逆编码后的地理描述集合。*/static async getGeoAddressFromLocation(latitude: number,longitude: number,maxItems: number = 1): Promise<Array<geoLocationManager.GeoAddress>> {const reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest = {latitude,longitude,maxItems,locale: 'zh',};try {const result = await geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest);return result || [];} catch (err) {LocationUtil.handleError(err, '逆地理编码失败');return [];}}/*** 逆地理编码:将坐标转换为地理描述。* @param latitude 纬度。* @param longitude 经度。* @returns 逆编码后的地理描述对象。*/static async getAddressFromLocation(latitude: number, longitude: number): Promise<geoLocationManager.GeoAddress> {const geoAddressList = await LocationUtil.getGeoAddressFromLocation(latitude, longitude, 1);return geoAddressList.length > 0 ? geoAddressList[0] : {};}/*** 获取当前的国家码。* @returns 当前国家码。*/static async getCountryCode(): Promise<string> {try {const result = await geoLocationManager.getCountryCode();return result?.country || '';} catch (err) {LocationUtil.handleError(err, '获取国家码失败');return '';}}/*** 根据指定的两个经纬度坐标点,计算两点间的直线距离(单位:米)。* @param from 起始坐标。* @param to 目标坐标。* @returns 两点间的直线距离。*/static calculateDistance(from: mapCommon.LatLng, to: mapCommon.LatLng): number {return map.calculateDistance(from, to);}/*** 根据指定的两个经纬度坐标点,计算两点间的直线距离(单位:米)。* @param fromLat 起始纬度。* @param fromLng 起始经度。* @param toLat 目标纬度。* @param toLng 目标经度。* @returns 两点间的直线距离。*/static calculateDistanceEasy(fromLat: number, fromLng: number, toLat: number, toLng: number): number {const fromLatLng: mapCommon.LatLng = { latitude: fromLat, longitude: fromLng };const toLatLng: mapCommon.LatLng = { latitude: toLat, longitude: toLng };return map.calculateDistance(fromLatLng, toLatLng);}/*** 错误处理方法。* @param error 错误对象,必须是 BusinessError 类型。* @param message 提示信息。* @returns 返回错误码。如果无法获取错误码,则返回默认值 -1。*/private static handleError(error: BusinessError, message: string): number {let errorCode = -1; // 默认错误码let errorMessage = '未知错误';if (error && typeof error.code === 'number') {errorCode = error.code;errorMessage = error.message || errorMessage;}// 记录错误日志LogUtil.error(`${message}: code=${errorCode}, message=${errorMessage}`);return errorCode;}/*** 获取错误消息。* @param code 错误码。* @param defaultMsg 默认错误消息。* @returns 错误消息。*/static getErrorMsg(code: number, defaultMsg: string): string {const errorMessages: Map<number, string> = new Map([[201, '权限校验失败!'],[202, '系统API权限校验失败!'],[401, '参数检查失败!'],[801, '该设备不支持此API!'],[3301000, '位置服务不可用!'],[3301100, '请开启位置功能开关!'],[3301200, '定位失败,未获取到定位结果!'],[3301300, '逆地理编码查询失败!'],[3301400, '地理编码查询失败!'],[3301500, '区域信息(包含国家码)查询失败!'],[3301600, '地理围栏操作失败!'],]);return errorMessages.get(code) || defaultMsg;}
}
代码如下:
import geoLocationManager from '@ohos.geoLocationManager';
import { BusinessError, Callback } from '@ohos.base';
import { LogUtil } from './LogUtil';
import { PermissionUtil } from './PermissionUtil';
import { map, mapCommon } from '@kit.MapKit';
/*** 定位工具类 (WGS-84坐标系)* author: CSDN-鸿蒙布道师* since: 2025/04/22*/
export class LocationUtil {/*** 判断位置服务是否已经使能(定位是否开启)。* @returns true 表示定位已开启,false 表示未开启。*/static isLocationEnabled(): boolean {return geoLocationManager.isLocationEnabled();}/*** 申请定位权限。* @returns true 表示授权成功,false 表示用户拒绝授权。*/static async requestLocationPermissions(): Promise<boolean> {const permissions: Array<string> = ['ohos.permission.LOCATION', 'ohos.permission.APPROXIMATELY_LOCATION'];let grant: boolean = await PermissionUtil.requestPermissions(permissions);if (!grant) {grant = await PermissionUtil.requestPermissionOnSetting(permissions);}return grant;}/*** 获取当前位置(简化版)。* @returns 当前位置信息。如果发生错误,则返回 null。*/static async getCurrentLocationEasy(): Promise<geoLocationManager.Location | null> {return LocationUtil.getCurrentLocation();}/*** 获取当前位置。* @param request 可选的定位请求参数。* @returns 当前位置信息。如果发生错误,则返回 null。*/static async getCurrentLocation(request?: geoLocationManager.CurrentLocationRequest | geoLocationManager.SingleLocationRequest): Promise<geoLocationManager.Location | null> {try {return await geoLocationManager.getCurrentLocation(request);} catch (err) {LocationUtil.handleError(err, '获取当前位置失败');return null; // 返回 null 表示发生错误}}/*** 开启位置变化订阅,并发起定位请求(简化版)。* @param callBack 回调函数。* @returns 成功返回 0,失败返回错误码。*/static onLocationChangeEasy(callBack: Callback<geoLocationManager.Location>): number {const defaultRequest: geoLocationManager.LocationRequest = {priority: geoLocationManager.LocationRequestPriority.FIRST_FIX,scenario: geoLocationManager.LocationRequestScenario.UNSET,timeInterval: 10,distanceInterval: 0,maxAccuracy: 0,};return LocationUtil.onLocationChange(defaultRequest, callBack);}/*** 开启位置变化订阅,并发起定位请求。* @param request 定位请求参数。* @param callBack 回调函数。* @returns 成功返回 0,失败返回错误码。*/static onLocationChange(request: geoLocationManager.LocationRequest | geoLocationManager.ContinuousLocationRequest,callBack: Callback<geoLocationManager.Location>): number {try {geoLocationManager.on('locationChange', request, callBack);return 0;} catch (err) {return LocationUtil.handleError(err, '开启位置变化订阅失败');}}/*** 关闭位置变化订阅,并删除对应的定位请求。* @param callback 不传则取消当前类型的所有订阅。* @returns 成功返回 0,失败返回错误码。*/static offLocationChange(callback?: Callback<geoLocationManager.Location>): number {try {if (callback) {geoLocationManager.off('locationChange', callback);} else {geoLocationManager.off('locationChange');}return 0;} catch (err) {return LocationUtil.handleError(err, '关闭位置变化订阅失败');}}/*** 判断地理编码与逆地理编码服务是否可用。* @returns true 表示服务可用,false 表示不可用。*/static isGeocoderAvailable(): boolean {return geoLocationManager.isGeocoderAvailable();}/*** 地理编码:将地理描述转换为具体坐标集合。* @param locationName 地理位置描述。* @param maxItems 返回结果的最大数量。* @returns 编码后的坐标集合。*/static async getGeoAddressFromLocationName(locationName: string,maxItems: number = 1): Promise<Array<geoLocationManager.GeoAddress>> {const geocodeRequest: geoLocationManager.GeoCodeRequest = {description: locationName,maxItems,locale: 'zh',};try {const result = await geoLocationManager.getAddressesFromLocationName(geocodeRequest);return result || [];} catch (err) {LocationUtil.handleError(err, '地理编码失败');return [];}}/*** 地理编码:将地理描述转换为具体坐标。* @param locationName 地理位置描述。* @returns 编码后的坐标对象。*/static async getAddressFromLocationName(locationName: string): Promise<geoLocationManager.GeoAddress> {const geoAddressList = await LocationUtil.getGeoAddressFromLocationName(locationName, 1);return geoAddressList.length > 0 ? geoAddressList[0] : {};}/*** 逆地理编码:将坐标转换为地理描述集合。* @param latitude 纬度。* @param longitude 经度。* @param maxItems 返回结果的最大数量。* @returns 逆编码后的地理描述集合。*/static async getGeoAddressFromLocation(latitude: number,longitude: number,maxItems: number = 1): Promise<Array<geoLocationManager.GeoAddress>> {const reverseGeocodeRequest: geoLocationManager.ReverseGeoCodeRequest = {latitude,longitude,maxItems,locale: 'zh',};try {const result = await geoLocationManager.getAddressesFromLocation(reverseGeocodeRequest);return result || [];} catch (err) {LocationUtil.handleError(err, '逆地理编码失败');return [];}}/*** 逆地理编码:将坐标转换为地理描述。* @param latitude 纬度。* @param longitude 经度。* @returns 逆编码后的地理描述对象。*/static async getAddressFromLocation(latitude: number, longitude: number): Promise<geoLocationManager.GeoAddress> {const geoAddressList = await LocationUtil.getGeoAddressFromLocation(latitude, longitude, 1);return geoAddressList.length > 0 ? geoAddressList[0] : {};}/*** 获取当前的国家码。* @returns 当前国家码。*/static async getCountryCode(): Promise<string> {try {const result = await geoLocationManager.getCountryCode();return result?.country || '';} catch (err) {LocationUtil.handleError(err, '获取国家码失败');return '';}}/*** 根据指定的两个经纬度坐标点,计算两点间的直线距离(单位:米)。* @param from 起始坐标。* @param to 目标坐标。* @returns 两点间的直线距离。*/static calculateDistance(from: mapCommon.LatLng, to: mapCommon.LatLng): number {return map.calculateDistance(from, to);}/*** 根据指定的两个经纬度坐标点,计算两点间的直线距离(单位:米)。* @param fromLat 起始纬度。* @param fromLng 起始经度。* @param toLat 目标纬度。* @param toLng 目标经度。* @returns 两点间的直线距离。*/static calculateDistanceEasy(fromLat: number, fromLng: number, toLat: number, toLng: number): number {const fromLatLng: mapCommon.LatLng = { latitude: fromLat, longitude: fromLng };const toLatLng: mapCommon.LatLng = { latitude: toLat, longitude: toLng };return map.calculateDistance(fromLatLng, toLatLng);}/*** 错误处理方法。* @param error 错误对象,必须是 BusinessError 类型。* @param message 提示信息。* @returns 返回错误码。如果无法获取错误码,则返回默认值 -1。*/private static handleError(error: BusinessError, message: string): number {let errorCode = -1; // 默认错误码let errorMessage = '未知错误';if (error && typeof error.code === 'number') {errorCode = error.code;errorMessage = error.message || errorMessage;}// 记录错误日志LogUtil.error(`${message}: code=${errorCode}, message=${errorMessage}`);return errorCode;}/*** 获取错误消息。* @param code 错误码。* @param defaultMsg 默认错误消息。* @returns 错误消息。*/static getErrorMsg(code: number, defaultMsg: string): string {const errorMessages: Map<number, string> = new Map([[201, '权限校验失败!'],[202, '系统API权限校验失败!'],[401, '参数检查失败!'],[801, '该设备不支持此API!'],[3301000, '位置服务不可用!'],[3301100, '请开启位置功能开关!'],[3301200, '定位失败,未获取到定位结果!'],[3301300, '逆地理编码查询失败!'],[3301400, '地理编码查询失败!'],[3301500, '区域信息(包含国家码)查询失败!'],[3301600, '地理围栏操作失败!'],]);return errorMessages.get(code) || defaultMsg;}
}

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

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

相关文章

SSM从入门到上手-全面讲解SSM框架的使用.

一、SSM框架整合 将Spring、Spring MVC和MyBatis结合在一起&#xff0c;形成一个高效且易于维护的Web应用程序架构。具体整合的方式如下&#xff1a; Spring管理Bean&#xff1a;Spring负责管理所有的Java对象&#xff0c;包括Service层、DAO层等。通过Spring的IoC容器进行依赖…

学员答题pk知识竞赛小程序怎么做

制作学员答题PK知识竞赛小程序&#xff0c;主要有以下步骤&#xff1a; 一、规划设计 明确需求&#xff1a;确定小程序的使用场景是校园知识竞赛、培训机构考核还是企业内部培训等。答题功能&#xff0c;规定答题的具体规则&#xff0c;包括题目类型&#xff08;单选、多选、…

视频分析设备平台EasyCVR视频技术驱动下,监控上墙全组件解析与组网应用方案

随着数字化进程的加速推进&#xff0c;视频监控技术在工业、商业、社区等诸多领域得到了广泛应用。尽管不同场景对监控功能的具体需求存在差异&#xff0c;但底层硬件架构具有显著的共性特征。实际部署中&#xff0c;仅需依据网络环境等实际情况&#xff0c;灵活调整设备的连接…

idea使用docker插件一键部署项目

一、首先保证我们电脑上已经安装了docker docker -v查看docker版本&#xff0c;如果不能识别&#xff0c;需要先下载docker destop&#xff0c;在官网下载正常安装即可。 安装成功就可以使用docker 命令了 二、idea下载docker插件并配置docker参数 我是通过tcp连接docker服务…

SQL Tuning Advisor

什么是SQL Tuning Advisor STA可以用来优化那些已经被发现的高负载SQL. 默认情况下, Oracle数据库在自动维护窗口中自动认证那些有问题的SQL并且执行优化建议&#xff0c;找寻提升高负载SQL执行计划性能的方法. ** 如何查看自动优化维护窗口产生的报告? ** SQL> set ser…

uniapp-商城-31-shop页面中的 我的订单

前面的章节讲了很多关于页面 布局 的知识。 现在来看看其他栏目&#xff0c;我的订单页面。 1 页面样式图 基本的样式包含shop页面 我的订单 点击我的订单&#xff0c;跳转到订单页面 点击订单的每一条订单&#xff0c;跳转到订单详情 2、创建订单页面 2.1 创建sub页面文件…

深入探讨JavaScript性能瓶颈与优化实战指南

JavaScript作为现代Web开发的核心语言,其性能直接影响用户体验与业务指标。随着2025年前端应用的复杂性持续增加,性能优化已成为开发者必须掌握的核心技能。本文将从性能瓶颈分析、优化策略、工具使用三个维度,结合实战案例,系统梳理JavaScript性能优化的关键路径。 一、Ja…

基于AI与drawio的图表生成技术及其在学术研究中的应用前景分析

一、研究背景与冲突 在当今数字化时代&#xff0c;学术研究与信息传播的方式发生了深刻变革。随着数据量的爆炸式增长以及研究内容的日益复杂&#xff0c;高效、精准地呈现研究成果变得至关重要。图表作为一种直观、简洁且信息承载量大的表达方式&#xff0c;在学术研究中扮演着…

uniapp 仿小红书轮播图效果

通过对小红书的轮播图分析&#xff0c;可得出以下总结&#xff1a; 1.单张图片时容器根据图片像素定高 2.多图时轮播图容器高度以首图为锚点 3.比首图长则固高左右留白 4.比首图短则固宽上下留白 代码如下&#xff1a; <template><view> <!--轮播--><s…

【ORACLE】记录一些ORACLE的merge into语句的BUG

【ORACLE】记录一些ORACLE的merge into语句的BUG 一、自相矛盾-DML重启动行为差异,违反acid原则 发现版本&#xff1a;10g ~ 23ai 这个用例在我之前的文章里有提过&#xff0c;ORACLE和PG系关于并发事务行为有一个非常大的差异&#xff0c;就是ORACLE在某些并发冲突的场景下会…

2025上海车展:光峰科技全球首发“灵境”智能车载光学系统

当AI为光赋予思想&#xff0c;汽车将会变成什么样&#xff1f;深圳光峰科技为您揭晓答案。 2025年4月23日&#xff0c;在刚刚开幕的“2025上海车展”上&#xff0c;全球领先的激光核心器件公司光峰科技举办了主题为“AI光影盛宴&#xff0c;智享未来出行”的媒体发布会&#x…

密码学的hash函数,哈希碰撞, collision resistance, BTC用到的SHA-256简介

密码学中的哈希函数、哈希碰撞、抗碰撞性&#xff08;collision resistance&#xff09;以及比特币中使用的 SHA-256 的简明介绍&#xff1a; &#x1f9e9; 一、哈希函数&#xff08;Hash Function&#xff09; 定义&#xff1a; 哈希函数是一种将任意长度的输入&#xff08;…

unity TEngine学习4

上一篇我们学习了UI部分&#xff0c;这一篇我们学习其他部分&#xff0c;按照老规矩还是先打开官方文档 ResourceModule 在官方文档里介绍了当前加载的设置&#xff0c;但是我们是小白看不懂&#xff0c;那就不管他内部怎么实现的&#xff0c;我们主要看下面的代码给的方法&am…

【AI训练环境搭建】在IDE(Pycharm或VSCode)上使用WSL2+Ubuntu22.04+Conda+Tensorflow+GPU进行机器学习训练

本次实践将在IDE&#xff08;Pycharm或VSCode&#xff09;上使用WSL2Ubuntu22.04TensorflowGPU进行机器学习训练。基本原理是在IDE中拉起WSL2中的Python解释器&#xff0c;并运行Python程序。要运行CondaTensorflowGPU你可能需要进行以下准备工作。 1. 此示例中将使用一个mnis…

【华为OD机试真题E卷】521、 机器人可活动的最大网格点数目 | 机试真题+思路参考+代码解析(E卷复用)(C++)

文章目录 一、题目题目描述输入输出样例1 一、代码与思路&#x1f9e0;C语言思路✅C代码 一、题目 参考链接&#xff1a;https://sars2025.blog.csdn.net/article/details/141748083 题目描述 现有一个机器人口&#xff0c;可放置于MxN的网格中任意位置&#xff0c;每个网格包…

windows端远程控制ubuntu运行脚本程序并转发ubuntu端脚本输出的网页

背景 对于一些只能在ubuntu上运行的脚本&#xff0c;并且这个脚本会在ubuntu上通过网页展示运行结果。我们希望可以使用windows远程操控ubuntu&#xff0c;在windows上查看网页内容。 方法 start cmd.exe /k "sshpass -p passwd ssh namexxx.xxx.xxx.xxx "cd /hom…

Vue3集成浏览器API实时语音识别

效果示例 用法 <!-- 浏览器语音识别 --> <BrowserSpeechRecognitionModal v-if"showModal" :isOpen"showModal" close"showModal false" confirm"handleRecognitionResult" />const showModal ref(false); const input…

k8s 手动续订证书

注意:如果是高可用环境,本文的操作需要在所有控制节点都执行。 查看证书是否过期 kubeadm certs check-expirationkubeadm certs renew可以续订任何特定证书,或者使用子命令all可以续订所有证书: kubeadm certs renew all使用 kubeadm 构建的集群通常会将admin.conf证书复…

每日一道leetcode(补充版)

1679. K 和数对的最大数目 - 力扣&#xff08;LeetCode&#xff09; 题目 给你一个整数数组 nums 和一个整数 k 。 每一步操作中&#xff0c;你需要从数组中选出和为 k 的两个整数&#xff0c;并将它们移出数组。 返回你可以对数组执行的最大操作数。 示例 1&#xff1a; …

基于Keras3.x使用CNN实现简单的猫狗分类

使用CNN实现简单的猫狗分类 完整代码见&#xff1a;基于Keras3.x使用CNN实现简单的猫狗分类&#xff0c;置信度约为&#xff1a;85% 文章目录 概述项目整体目录环境版本注意 环境准备下载miniconda新建虚拟环境基于conda虚拟环境新建Pycharm项目下载分类需要用到的依赖 数据准备…