diff --git a/src/static/map.html b/src/static/map.html index 1a76cef..e991984 100644 --- a/src/static/map.html +++ b/src/static/map.html @@ -712,8 +712,8 @@ point.lat ); - // 位置变化超过2米就更新,或者精度提升超过5米 - if (distance > 2 || + // 位置变化超过1米就更新,或者精度提升超过5米(降低阈值减少延迟) + if (distance > 1 || (accuracy < this.state.currentLocation.accuracy - 5) || (accuracy < 50 && this.state.currentLocation.accuracy >= 50)) { shouldUpdate = true; @@ -789,8 +789,8 @@ point.lat ); - // 位置变化超过2米就更新,或者精度提升超过5米 - if (distance > 2 || + // 位置变化超过1米就更新,或者精度提升超过5米(降低阈值减少延迟) + if (distance > 1 || (accuracy < this.state.currentLocation.accuracy - 5) || (accuracy < 50 && this.state.currentLocation.accuracy >= 50)) { shouldUpdate = true; @@ -837,7 +837,7 @@ enableHighAccuracy: true, // 使用GPS精确定位 timeout: 6000 // 6秒超时 }); - }, 500); // 每0.5秒更新一次,提高实时性和灵敏度 + }, 300); // 每0.3秒更新一次,提高实时性和灵敏度,减少延迟 // 保存geolocation实例,以便后续使用 this.baiduGeolocation = geolocation; @@ -1350,17 +1350,20 @@ return; } - // 如果已经有待处理的更新,取消它,重新调度(确保使用最新数据) - if (this.updateMarkerTimer) { - cancelAnimationFrame(this.updateMarkerTimer); - } - - // 使用requestAnimationFrame实现平滑更新,保持实时性 - // 对于位置更新,立即执行;对于方向更新,异步执行 - this.updateMarkerTimer = requestAnimationFrame(() => { - this.updateMarkerTimer = null; + // 移动时立即更新位置,减少延迟;静止时使用requestAnimationFrame平滑更新 + if (this.isMoving) { + // 移动时直接更新,不使用requestAnimationFrame延迟 this._doUpdateLocationMarker(); - }); + } else { + // 静止时使用requestAnimationFrame平滑更新 + if (this.updateMarkerTimer) { + cancelAnimationFrame(this.updateMarkerTimer); + } + this.updateMarkerTimer = requestAnimationFrame(() => { + this.updateMarkerTimer = null; + this._doUpdateLocationMarker(); + }); + } }, /** @@ -1375,7 +1378,8 @@ try { // 优先更新位置(立即执行,不等待方向更新) if (typeof this.overlays.locationMarker.setPosition === 'function') { - // 直接更新位置,实时跟随移动(不检查距离,每次都更新以确保平滑) + // 直接更新位置,实时跟随移动 + // 移动时立即更新,静止时也可以立即更新(已通过updateLocationMarker控制) this.overlays.locationMarker.setPosition(point); } else { // 如果不支持setPosition,检查位置是否变化(降低阈值,提高灵敏度) @@ -1393,16 +1397,16 @@ } // 实时更新方向(使用角度差值计算,考虑0-360度边界) - // 移动时提高阈值(2度),减少抖动;静止时降低阈值(1度),保持响应性 - const headingThreshold = this.isMoving ? 2 : 1; + // 统一使用1度阈值,确保方向更新及时准确 + const headingThreshold = 1; const headingChanged = !this.lastHeading || Math.abs(this.angleDifference(this.state.currentHeading, this.lastHeading)) >= headingThreshold; if (headingChanged) { const oldHeading = this.lastHeading; this.lastHeading = this.state.currentHeading; - // 异步更新图标(使用requestAnimationFrame确保平滑,不阻塞位置更新) - requestAnimationFrame(() => { + // 移动时立即更新图标,减少延迟;静止时使用requestAnimationFrame平滑更新 + const updateIcon = () => { this.createRotatedLocationIcon(this.state.currentHeading).then((icon) => { if (this.overlays.locationMarker) { // 优先使用setIcon更新(不删除重建) @@ -1421,7 +1425,15 @@ // 恢复旧的方向值 this.lastHeading = oldHeading; }); - }); + }; + + if (this.isMoving) { + // 移动时立即更新,不使用requestAnimationFrame延迟 + updateIcon(); + } else { + // 静止时使用requestAnimationFrame平滑更新 + requestAnimationFrame(updateIcon); + } } } catch (e) { // 如果更新失败,重新创建标记 @@ -1616,6 +1628,20 @@ return diff; }, + /** + * 判断方向是否为南北方向(需要反转) + * 南北方向:0度(正北)、180度(正南),以及0-45度、135-225度、315-360度范围 + * 东西方向:90度(正东)、270度(正西),以及45-135度、225-315度范围 + */ + isNorthSouthDirection(heading) { + // 归一化到0-360度 + const normalized = this.normalizeHeading(heading); + // 南北方向:0-45度、135-225度、315-360度 + return (normalized >= 0 && normalized <= 45) || + (normalized >= 135 && normalized <= 225) || + (normalized >= 315 && normalized <= 360); + }, + /** * 移动平均滤波(减少抖动) * 移动时使用更强的平滑,静止时使用较弱的平滑 @@ -1627,8 +1653,8 @@ } // 根据移动状态动态调整历史记录大小 - // 移动时使用更多样本(10个)进行更强的平滑,静止时使用较少样本(5个)保持响应性 - const targetHistorySize = this.isMoving ? 10 : 5; + // 移动时使用较少样本(3个)减少延迟,静止时使用较多样本(5个)保持平滑 + const targetHistorySize = this.isMoving ? 3 : 5; if (!this.headingHistorySize) { this.headingHistorySize = targetHistorySize; } else { @@ -1643,7 +1669,7 @@ } // 如果历史记录不足,直接返回原始值 - const minHistorySize = this.isMoving ? 5 : 3; // 移动时需要更多样本 + const minHistorySize = this.isMoving ? 1 : 2; // 移动时减少样本要求,降低延迟,提高响应性 if (this.headingHistory.length < minHistorySize) { return rawHeading; } @@ -1823,17 +1849,22 @@ const oldHeading = this.state.currentHeading; const diff = Math.abs(this.angleDifference(newHeading, oldHeading)); - // 移动时提高阈值(2度),减少抖动;静止时降低阈值(1度),保持响应性 - const threshold = this.isMoving ? 2 : 1; + // 统一使用1度阈值,确保方向更新及时准确 + const threshold = 1; if (diff >= threshold || oldHeading === 0) { this.state.currentHeading = newHeading; console.log('方向更新:', newHeading.toFixed(1), '度', '变化:', diff.toFixed(1), '度', this.isMoving ? '(移动中)' : '(静止)'); if (this.state.currentLocation) { - requestAnimationFrame(() => { - this.updateLocationMarker(); - }); + // 移动时立即更新,静止时使用requestAnimationFrame + if (this.isMoving) { + this.updateLocationMarker(); // 移动时直接调用,已在updateLocationMarker中处理 + } else { + requestAnimationFrame(() => { + this.updateLocationMarker(); + }); + } } } }, @@ -1934,10 +1965,19 @@ correctedHeading = rawHeading; // 暂时保持原样 console.log('横屏+静止时方向:', rawHeading.toFixed(1), '度 ->', correctedHeading.toFixed(1), '度'); } - // 竖屏 + 移动:需要反转180度 + // 竖屏 + 移动:根据移动方向判断是否需要反转 + // 东西方向(90度、270度)时方向是准的,不需要反转 + // 南北方向(0度、180度)时方向是反的,需要反转180度 else if (this.isMoving && isPortrait) { - correctedHeading = (rawHeading + 180) % 360; - console.log('竖屏+移动时方向反转:', rawHeading.toFixed(1), '度 ->', correctedHeading.toFixed(1), '度'); + if (this.isNorthSouthDirection(rawHeading)) { + // 南北方向,需要反转180度 + correctedHeading = (rawHeading + 180) % 360; + console.log('竖屏+移动(南北方向)时方向反转:', rawHeading.toFixed(1), '度 ->', correctedHeading.toFixed(1), '度'); + } else { + // 东西方向,保持原样 + correctedHeading = rawHeading; + console.log('竖屏+移动(东西方向)时方向保持:', rawHeading.toFixed(1), '度'); + } } // 竖屏 + 静止:需要反转180度 else if (!this.isMoving && isPortrait) {