HarmonyOS 鸿蒙Next应用开发与华为地图之经纬度精度偏差-优化方案

HarmonyOS 鸿蒙Next应用开发与华为地图之经纬度精度偏差-优化方案

问题背景

  • 在鸿蒙App开发中,调用鸿蒙定位服务API获取的当前定位坐标后,传入华为地图后,在华为地图上显示的定位坐标,与实际预期的定位位置不一样
  • 例如:鸿蒙定位服务API获取的当前定位坐标,预期在华为地图上应该显示在湖附近,但是实际华为地图上显示的位置,在几百米外的陆地上。具体效果见下面截图
  • 即,应用内通过鸿蒙定位服务API获取的当前定位坐标,与华为地图中显示的坐标位置存在偏差

image.png

问题原因

image.png

问题原因总结

  • 华为官方设计上存在不一致:华为地图需要使用标准的大陆的GCJ02 坐标系,与鸿蒙定位服务API的WGS84坐标系,设计上不一致

修复方案:

核心答案

  • 封装一套坐标系转换的方法,将WGS84坐标系的坐标转换为GCJ02坐标系的坐标

实现步骤

  1. 鸿蒙原生通过鸿蒙定位服务API获取到坐标后,调用封装的经纬度坐标系转换方法,将转换后的坐标,传入到华为地图中显示

经纬度坐标转换方法,见如下代码设计思路

image.png

经纬度坐标转换,代码设计思路

  1. 先定义一个接受经度、纬度两个参数的方法,并返回number数组,如下:gcj02ToWgs84(lng: number, lat: number)
  2. 判断是否为国内坐标,若是则继续转化,否则退出
  3. 封装一个转换经度的方法,如下:transformLng
  4. 封装一个转换纬度的方法,如下:transformLat
  5. 再经过固定算法,在gcj02ToWgs84返回number数组

完整代码

const PI = Math.PI;
const a = 6378245.0;
const ee = 0.00669342162296594323;

function outOfChina(lng: number, lat: number): boolean {
  if (lng < 72.004 || lng > 137.8347) {
    return true;
  }
  if (lat < 0.8293 || lat > 55.8271) {
    return true;
  }
  return false;
}

function transformLat(lng: number, lat: number): number {
  let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
  ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
  ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
  ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
  return ret;
}

function transformLng(lng: number, lat: number): number {
  let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
  ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
  ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
  ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
  return ret;
}

function gcj02ToWgs84(lng: number, lat: number): number[] {
  if (outOfChina(lng, lat)) {
    return [lng, lat];
  }
  let dlat = transformLat(lng - 105.0, lat - 35.0);
  let dlng = transformLng(lng - 105.0, lat - 35.0);
  let radlat = lat / 180.0 * PI;
  let magic = Math.sin(radlat);
  magic = 1 - ee * magic * magic;
  let sqrtmagic = Math.sqrt(magic);
  dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
  let mglat = lat + dlat;
  let mglng = lng + dlng;
  return [lng * 2 - mglng, lat * 2 - mglat];
}

总结

  • 鸿蒙地图相关开发中,若存在应用内app获取定位后,需要在华为地图中显示定位坐标位置,则需要转换坐标。
  • 开发者需了解鸿蒙中此种经纬度坐标系,不同标准。若遇到类似问题,可快速解决,无需查阅很多资料花费较多时间来定位此种类型的问题
  • 若遇到类似定位相关的问题,查阅鸿蒙官网API时,需留意坐标系相关的说明,可快速定界出是否是坐标系的问题

更多关于HarmonyOS 鸿蒙Next应用开发与华为地图之经纬度精度偏差-优化方案的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

鸿蒙Next应用开发中优化华为地图经纬度精度偏差的方案如下:

  1. 使用HarmonyOS Location Kit提供的GNSS定位服务获取高精度坐标
  2. 调用华为地图SDK的CoordinateConverter.convert()方法进行WGS84到GCJ02坐标系的转换
  3. 在MapView初始化时设置setMyLocationScale(100)提高定位精度显示
  4. 通过LocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)启用高精度模式
  5. 实现LocationCallback接口实时接收位置更新,过滤低精度定位结果

定位结果建议保留6位小数精度,关键参数配置:

  • 最小更新间隔:1000ms
  • 最小位移变化:0.1m
  • 定位超时:30s

更多关于HarmonyOS 鸿蒙Next应用开发与华为地图之经纬度精度偏差-优化方案的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个典型的坐标系转换问题。HarmonyOS定位服务使用WGS84坐标系,而华为地图在中国大陆地区使用GCJ02坐标系,导致直接显示时出现位置偏移。

解决方案的核心是进行WGS84到GCJ02的坐标转换。您提供的代码已经实现了这一转换逻辑,主要包括:

  1. 判断坐标是否在中国境内(outOfChina)
  2. 实现经纬度转换算法(transformLat/transformLng)
  3. 完成最终坐标转换(gcj02ToWgs84)

在实际应用中,建议:

  1. 将坐标转换逻辑封装为独立工具类
  2. 在获取定位后立即进行转换
  3. 使用转换后的坐标显示在地图上

这种方案能有效解决因坐标系差异导致的位置偏移问题。

回到顶部