华为地图在中国大陆使用GCJ-02坐标系,但有些服务使用的是WGS-84坐标系,可以通过坐标系切换到WGS-84坐标系来精确计算两个坐标之间的距离。GCJ-02实际上是WGS-84经过加密后的坐标,所以直接用WGS-84的计算方法可能不适用。Map Kit的距离计算只有一个接口,无法自定义计算公式。
import { map, mapCommon } from '@kit.MapKit';
let locations: Array<mapCommon.CoordinateLatLng> = [
{
// 输入香港坐标和WGS84坐标系,若当前地图站点使用GCJ02坐标系,返回GCJ02坐标系和转换后的香港坐标(输入的坐标转换为GCJ02坐标系)
coordinateType: mapCommon.CoordinateType.WGS84,
location: { latitude: 22.280556, longitude: 114.984000 }
}
];
// 包含await的外层方法需要添加async关键字
async function rectifyCoordinate(context: Context | undefined): Promise<mapCommon.CoordinateLatLng[]> {
let arr: Array<mapCommon.CoordinateLatLng> = await map.rectifyCoordinate(context, locations);
return arr;
}
/*
* 使用 Haversine 公式计算两个经纬度点之间的距离。
* @param lon1 - 第一个点的经度
* @param lat1 - 第一个点的纬度
* @param lon2 - 第二个点的经度
* @param lat2 - 第二个点的纬度
* @returns 两点之间的距离(公里)
*/
function haversine(lon1: number, lat1: number, lon2: number, lat2: number): number {
const R = 6371; // 地球半径,单位为公里
const radians = (degrees: number) => degrees * Math.PI / 180.0; // 将角度转换为弧度的函数
const φ1 = radians(lat1); // 将第一个点的纬度转换为弧度
const φ2 = radians(lat2); // 将第二个点的纬度转换为弧度
const λ1 = radians(lon1); // 将第一个点的经度转换为弧度
const λ2 = radians(lon2); // 将第二个点的经度转换为弧度
const Δφ = φ2 - φ1; // 计算两个纬度的差值
const Δλ = λ2 - λ1; // 计算两个经度的差值
const a = Math.sin(Δφ / 2)**2 + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2)**2; // 计算Haversine公式中的a值
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); // 计算Haversine公式中的c值(中心角)
const distance = R * c; // 计算两点之间的距离
return distance; // 返回计算的距离
}
@Entry
@Component
struct haversinePage {
build() {
Column() {
Button('Calculate Distance')
.onClick(() => {
haversine(114.984000, 22.280556, 115.0, 22.3);
rectifyCoordinate(this.getUIContext().getHostContext());
});
};
}
}