From 019a54d5dd3c3fbfa80544f8e66c78909c692db6 Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Wed, 14 Jan 2026 14:44:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E6=A0=87=E5=AE=9A=E4=BD=8D=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/static/map.html | 79 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/src/static/map.html b/src/static/map.html index e1b9bcd..acf71c7 100644 --- a/src/static/map.html +++ b/src/static/map.html @@ -618,6 +618,18 @@ console.log('已开启百度地图SDK辅助定位'); + // 计算两点之间的距离(米)- 供多个函数使用 + const calculateDistance = (lng1, lat1, lng2, lat2) => { + const R = 6371000; // 地球半径(米) + const dLat = (lat2 - lat1) * Math.PI / 180; + const dLng = (lng2 - lng1) * Math.PI / 180; + const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * + Math.sin(dLng / 2) * Math.sin(dLng / 2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + return R * c; + }; + // 先快速获取位置(使用较短的超时时间,优先显示位置) let isFirstLocation = true; @@ -675,8 +687,26 @@ if (point.lng && point.lat && !isNaN(point.lng) && !isNaN(point.lat) && Math.abs(point.lng) <= 180 && Math.abs(point.lat) <= 90) { - // 只更新精度更好的位置 - if (!this.state.currentLocation || accuracy < this.state.currentLocation.accuracy) { + let shouldUpdate = false; + + if (!this.state.currentLocation) { + shouldUpdate = true; + } else { + // 计算位置变化距离 + const distance = calculateDistance( + this.state.currentLocation.lng, + this.state.currentLocation.lat, + point.lng, + point.lat + ); + + // 如果位置变化超过3米,或者精度提升超过10米,则更新 + if (distance > 3 || accuracy < this.state.currentLocation.accuracy - 10) { + shouldUpdate = true; + } + } + + if (shouldUpdate) { console.log('精确位置更新 - 经度:', point.lng, '纬度:', point.lat, '精度:', accuracy, '米'); this.state.currentLocation = { lng: point.lng, @@ -696,7 +726,7 @@ // 先快速获取位置 getQuickPosition(); - // 持续监听位置变化(使用定时器定期获取,优化精度) + // 持续监听位置变化(使用定时器定期获取,实时更新) this.state.watchLocationTimer = setInterval(() => { geolocation.getCurrentPosition((result) => { const status = geolocation.getStatus(); @@ -708,12 +738,37 @@ if (point.lng && point.lat && !isNaN(point.lng) && !isNaN(point.lat) && Math.abs(point.lng) <= 180 && Math.abs(point.lat) <= 90) { - // 只更新精度更好的位置(精度提升超过10米,或者精度小于50米) - if (!this.state.currentLocation || - (accuracy < this.state.currentLocation.accuracy - 10) || - (accuracy < 50 && this.state.currentLocation.accuracy >= 50)) { + let shouldUpdate = false; + + if (!this.state.currentLocation) { + // 如果没有当前位置,直接更新 + shouldUpdate = true; + } else { + // 计算位置变化距离 + const distance = calculateDistance( + this.state.currentLocation.lng, + this.state.currentLocation.lat, + point.lng, + point.lat + ); - console.log('位置更新 - 经度:', point.lng, '纬度:', point.lat, '精度:', accuracy, '米'); + // 如果位置变化超过5米,或者精度提升超过10米,则更新 + if (distance > 5 || + (accuracy < this.state.currentLocation.accuracy - 10) || + (accuracy < 50 && this.state.currentLocation.accuracy >= 50)) { + shouldUpdate = true; + } + } + + if (shouldUpdate) { + const oldLocation = this.state.currentLocation; + const distance = oldLocation ? calculateDistance( + oldLocation.lng, oldLocation.lat, point.lng, point.lat + ) : 0; + + console.log('位置更新 - 经度:', point.lng, '纬度:', point.lat, + '精度:', accuracy, '米', + oldLocation ? `移动距离: ${distance.toFixed(2)}米` : ''); this.state.currentLocation = { lng: point.lng, @@ -726,9 +781,9 @@ } }, { enableHighAccuracy: true, // 使用GPS精确定位 - timeout: 10000 // 10秒超时 + timeout: 8000 // 8秒超时 }); - }, 5000); // 每5秒更新一次,优化精度 + }, 2000); // 每2秒更新一次,实时跟踪移动 // 保存geolocation实例,以便后续使用 this.baiduGeolocation = geolocation; @@ -1358,7 +1413,9 @@ // 旋转画布(heading是相对于正北的角度,需要转换为相对于画布的角度) // 百度地图中,heading是相对于正北的角度(0-360),顺时针为正 // 画布中,0度是向右,需要转换 - const rotation = (heading - 90) * Math.PI / 180; // 转换为弧度并调整方向 + // 如果方向反了,尝试反转:使用 (90 - heading) 或 (270 - heading) + // 或者添加180度来反转:heading + 180 + const rotation = (90 - heading) * Math.PI / 180; // 反转方向:从 (heading - 90) 改为 (90 - heading) ctx.rotate(rotation); // 绘制图片(居中,保持原始宽高比)