diff --git a/package-lock.json b/package-lock.json index 66f3eae..fa2f90e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "clipboard": "^2.0.11", "crypto-js": "^4.2.0", "dayjs": "^1.11.13", + "geomagnetism": "^0.2.0", "lodash-es": "^4.17.21", "pinia": "^2.3.0", "pinia-plugin-persistedstate": "^4.2.0", @@ -7409,6 +7410,11 @@ "node": ">=6.9.0" } }, + "node_modules/geomagnetism": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/geomagnetism/-/geomagnetism-0.2.0.tgz", + "integrity": "sha512-dO8HJrXqah244nMe+pU5m52L90SMoi4lDA0AV3xunRxogloYV+s3aYWCW72VMMfiYis+YSAlhoKktw8aLMiJbw==" + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://repo.huaweicloud.com/repository/npm/get-caller-file/-/get-caller-file-2.0.5.tgz", diff --git a/package.json b/package.json index de6096a..3e2edac 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "clipboard": "^2.0.11", "crypto-js": "^4.2.0", "dayjs": "^1.11.13", + "geomagnetism": "^0.2.0", "lodash-es": "^4.17.21", "pinia": "^2.3.0", "pinia-plugin-persistedstate": "^4.2.0", diff --git a/src/hooks/useGeomagnetism.js b/src/hooks/useGeomagnetism.js new file mode 100644 index 0000000..7abe834 --- /dev/null +++ b/src/hooks/useGeomagnetism.js @@ -0,0 +1,66 @@ +import geomagnetism from 'geomagnetism'; + +export function useGeomagnetism() { + const bd09toWgs84 = (bd_lat, bd_lng) => { + const x_pi = (3.14159265358979324 * 3000.0) / 180.0; + const x = Number(bd_lng) - 0.0065; + const y = Number(bd_lat) - 0.006; + const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); + const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); + return { + lat: z * Math.sin(theta) - 0.002, + lng: z * Math.cos(theta) - 0.005 + }; + }; + + const calculate = (latitude, longitude, altitude = 0) => { + try { + // 强制转换 + const numLat = parseFloat(latitude); + const numLng = parseFloat(longitude); + + if (isNaN(numLat) || isNaN(numLng)) { + console.warn('磁偏角计算: 无效的经纬度', { latitude, longitude }); + return { declination: 0, success: false }; + } + + const wgs = bd09toWgs84(numLat, numLng); + + // 获取地磁模型 - geomagnetism.model(date) 返回模型实例 + const model = geomagnetism.model(new Date()); + + if (!model || typeof model.point !== 'function') { + console.error("无法加载地磁模型或模型没有point方法"); + return { declination: 0, success: false }; + } + + // point() 方法接受数组参数 [lat, lon, altitude] + // 根据库源码,参数顺序是 [lat, lon, altitude] + const info = model.point([wgs.lat, wgs.lng, altitude]); + + if (!info) { + console.error('model.point() 返回 null 或 undefined'); + return { declination: 0, success: false }; + } + + // 根据 geomagnetism 库的类型定义,返回值属性名是 decl(不是 declination) + const decl = info.decl; + + if (typeof decl !== 'number' || isNaN(decl)) { + console.warn('磁偏角值无效:', decl, 'info对象:', info); + return { declination: 0, success: false }; + } + + return { + declination: decl, + success: true + }; + } catch (e) { + console.error('磁偏角计算过程出错:', e); + console.error('错误堆栈:', e.stack); + return { declination: 0, success: false }; + } + }; + + return { calculate }; +} \ No newline at end of file