UNPKG

vuepress-plugin-photomap

Version:

VuePress2插件,用于在文章中插入照片地图组件,类似Apple相册的PhotoMap功能

134 lines (133 loc) 4.23 kB
/** * 坐标转换工具函数 */ /** * 度分秒(DMS)转十进制度(DD) */ export const dmsToDecimal = (dms, direction) => { if (!dms || dms.length < 3) { throw new Error('Invalid DMS format'); } const [degrees, minutes, seconds] = dms; let decimal = degrees + minutes / 60 + seconds / 3600; // 南纬和西经为负值 if (direction === 'S' || direction === 'W') { decimal = -decimal; } return decimal; }; /** * 十进制度(DD)转度分秒(DMS) */ export const decimalToDMS = (decimal, isLatitude = true) => { const absDecimal = Math.abs(decimal); const degrees = Math.floor(absDecimal); const minutesFloat = (absDecimal - degrees) * 60; const minutes = Math.floor(minutesFloat); const seconds = (minutesFloat - minutes) * 60; let direction; if (isLatitude) { direction = decimal >= 0 ? 'N' : 'S'; } else { direction = decimal >= 0 ? 'E' : 'W'; } return { degrees, minutes, seconds: Math.round(seconds * 1000) / 1000, // 保留3位小数 direction }; }; /** * 验证经纬度坐标是否有效 */ export const validateCoordinates = (lat, lng) => { return (typeof lat === 'number' && typeof lng === 'number' && !isNaN(lat) && !isNaN(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180); }; /** * 计算两点之间的距离(使用Haversine公式) * @param coord1 起点坐标 * @param coord2 终点坐标 * @returns 距离(单位:米) */ export const calculateDistance = (coord1, coord2) => { const R = 6371000; // 地球半径(米) const φ1 = (coord1.latitude * Math.PI) / 180; const φ2 = (coord2.latitude * Math.PI) / 180; const Δφ = ((coord2.latitude - coord1.latitude) * Math.PI) / 180; const Δλ = ((coord2.longitude - coord1.longitude) * Math.PI) / 180; const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + Math.cos1) * Math.cos2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; }; /** * 计算地理边界框 */ export const calculateBounds = (coordinates) => { if (coordinates.length === 0) { throw new Error('No coordinates provided'); } let north = coordinates[0].latitude; let south = coordinates[0].latitude; let east = coordinates[0].longitude; let west = coordinates[0].longitude; coordinates.forEach(coord => { north = Math.max(north, coord.latitude); south = Math.min(south, coord.latitude); east = Math.max(east, coord.longitude); west = Math.min(west, coord.longitude); }); return { north, south, east, west }; }; /** * 计算地理中心点 */ export const calculateCenter = (coordinates) => { if (coordinates.length === 0) { throw new Error('No coordinates provided'); } if (coordinates.length === 1) { return coordinates[0]; } let x = 0; let y = 0; let z = 0; coordinates.forEach(coord => { const lat = (coord.latitude * Math.PI) / 180; const lng = (coord.longitude * Math.PI) / 180; x += Math.cos(lat) * Math.cos(lng); y += Math.cos(lat) * Math.sin(lng); z += Math.sin(lat); }); const total = coordinates.length; x /= total; y /= total; z /= total; const centralLongitude = Math.atan2(y, x); const centralSquareRoot = Math.sqrt(x * x + y * y); const centralLatitude = Math.atan2(z, centralSquareRoot); return { latitude: (centralLatitude * 180) / Math.PI, longitude: (centralLongitude * 180) / Math.PI }; }; /** * 格式化坐标显示 */ export const formatCoordinate = (coord, format = 'decimal') => { if (format === 'dms') { const latDMS = decimalToDMS(coord.latitude, true); const lngDMS = decimalToDMS(coord.longitude, false); return `${latDMS.degrees}°${latDMS.minutes}'${latDMS.seconds.toFixed(1)}"${latDMS.direction} ${lngDMS.degrees}°${lngDMS.minutes}'${lngDMS.seconds.toFixed(1)}"${lngDMS.direction}`; } return `${coord.latitude.toFixed(6)}, ${coord.longitude.toFixed(6)}`; };