84 lines
2.5 KiB
JavaScript
84 lines
2.5 KiB
JavaScript
/**
|
||
* 坐标相关计算工具函数
|
||
*/
|
||
|
||
/**
|
||
* 将度分秒转换为十进制度数
|
||
* @param {number} degrees - 度
|
||
* @param {number} minutes - 分
|
||
* @param {number} seconds - 秒
|
||
* @returns {number} 十进制度数
|
||
*/
|
||
export function dmsToDecimal(degrees, minutes, seconds) {
|
||
return degrees + minutes / 60 + seconds / 3600;
|
||
}
|
||
|
||
/**
|
||
* 将十进制度数转换为度分秒
|
||
* @param {number} decimal - 十进制度数
|
||
* @returns {{degrees: number, minutes: number, seconds: number}}
|
||
*/
|
||
export function decimalToDms(decimal) {
|
||
const absDecimal = Math.abs(decimal);
|
||
const degrees = Math.floor(absDecimal);
|
||
const minutesDecimal = (absDecimal - degrees) * 60;
|
||
const minutes = Math.floor(minutesDecimal);
|
||
const seconds = (minutesDecimal - minutes) * 60;
|
||
|
||
return {
|
||
degrees: decimal < 0 ? -degrees : degrees,
|
||
minutes,
|
||
seconds: parseFloat(seconds.toFixed(6))
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 计算两点间的距离(Haversine公式)
|
||
* @param {number} lat1 - 点1纬度(十进制度数)
|
||
* @param {number} lon1 - 点1经度(十进制度数)
|
||
* @param {number} lat2 - 点2纬度(十进制度数)
|
||
* @param {number} lon2 - 点2经度(十进制度数)
|
||
* @returns {number} 距离(米)
|
||
*/
|
||
export function haversineDistance(lat1, lon1, lat2, lon2) {
|
||
const R = 6371000; // 地球半径(米)
|
||
const φ1 = lat1 * Math.PI / 180;
|
||
const φ2 = lat2 * Math.PI / 180;
|
||
const Δφ = (lat2 - lat1) * Math.PI / 180;
|
||
const Δλ = (lon2 - lon1) * Math.PI / 180;
|
||
|
||
const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
|
||
Math.cos(φ1) * Math.cos(φ2) *
|
||
Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
|
||
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||
|
||
return R * c;
|
||
}
|
||
|
||
/**
|
||
* 计算平面坐标两点间的距离(勾股定理)
|
||
* @param {number} x1 - 点1 X坐标
|
||
* @param {number} y1 - 点1 Y坐标
|
||
* @param {number} x2 - 点2 X坐标
|
||
* @param {number} y2 - 点2 Y坐标
|
||
* @returns {number} 距离
|
||
*/
|
||
export function planarDistance(x1, y1, x2, y2) {
|
||
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
||
}
|
||
|
||
/**
|
||
* 格式化坐标为字符串
|
||
* @param {number} decimal - 十进制度数
|
||
* @param {string} type - 类型 'lat' 或 'lon'
|
||
* @returns {string} 格式化的坐标字符串
|
||
*/
|
||
export function formatCoordinate(decimal, type) {
|
||
const dms = decimalToDms(decimal);
|
||
const direction = type === 'lat'
|
||
? (decimal >= 0 ? 'N' : 'S')
|
||
: (decimal >= 0 ? 'E' : 'W');
|
||
|
||
return `${Math.abs(dms.degrees)}° ${dms.minutes}' ${dms.seconds.toFixed(2)}" ${direction}`;
|
||
}
|