/** * 坐标相关计算工具函数 */ /** * 将度分秒转换为十进制度数 * @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}`; }