diff --git a/src/static/map.html b/src/static/map.html
index acf71c7..a1367fe 100644
--- a/src/static/map.html
+++ b/src/static/map.html
@@ -412,6 +412,8 @@
},
locationIconCache: null,
baiduGeolocation: null,
+ lastHeading: null, // 记录上一次的方向,用于避免频繁更新图标
+ updateMarkerTimer: null, // 防抖定时器
elements: {
panel: null,
tree: null,
@@ -1283,38 +1285,116 @@
},
/**
- * 更新定位标记
+ * 更新定位标记(使用requestAnimationFrame实现平滑更新,避免闪烁)
*/
updateLocationMarker() {
// 确保地图已加载完成
if (!this.map || !this.state.mapLoaded) {
- // 静默返回,不输出警告(地图可能还在加载中)
return;
}
- // 如果没有位置信息,静默返回(定位是异步的,需要时间获取)
+ // 如果没有位置信息,静默返回
if (!this.state.currentLocation) {
- // 不输出警告,因为定位是异步过程,这是正常情况
return;
}
+ // 如果已经有待处理的更新,取消它,重新调度(确保使用最新数据)
+ if (this.updateMarkerTimer) {
+ cancelAnimationFrame(this.updateMarkerTimer);
+ }
+
+ // 使用requestAnimationFrame实现平滑更新,保持实时性
+ this.updateMarkerTimer = requestAnimationFrame(() => {
+ this.updateMarkerTimer = null;
+ this._doUpdateLocationMarker();
+ });
+ },
+
+ /**
+ * 实际执行更新定位标记(实时更新位置和方向)
+ */
+ _doUpdateLocationMarker() {
const { lng, lat } = this.state.currentLocation;
-
- // 创建百度地图点(已转换为BD09坐标)
const point = new BMapGL.Point(lng, lat);
- console.log('更新定位标记 - 坐标:', lng, lat, '方向:', this.state.currentHeading);
-
- // 创建带方向的图标(异步加载图片)
- this.createRotatedLocationIcon(this.state.currentHeading).then((icon) => {
- // 如果标记已存在,更新位置和图标
- if (this.overlays.locationMarker) {
- this.map.removeOverlay(this.overlays.locationMarker);
+ // 如果标记已存在,直接更新(避免删除重建)
+ if (this.overlays.locationMarker) {
+ try {
+ // 更新位置(百度地图GL API支持setPosition)
+ if (typeof this.overlays.locationMarker.setPosition === 'function') {
+ this.overlays.locationMarker.setPosition(point);
+ } else {
+ // 如果不支持setPosition,检查位置是否变化
+ const currentPoint = this.overlays.locationMarker.getPosition();
+ if (!currentPoint ||
+ Math.abs(currentPoint.lng - lng) > 0.00001 ||
+ Math.abs(currentPoint.lat - lat) > 0.00001) {
+ // 位置变化,需要更新(但尽量不删除重建)
+ const needsRecreate = true;
+ if (needsRecreate) {
+ // 保存当前图标,避免重新创建
+ const currentIcon = this.overlays.locationMarker.getIcon();
+ this.map.removeOverlay(this.overlays.locationMarker);
+ this.overlays.locationMarker = new BMapGL.Marker(point, { icon: currentIcon });
+ this.map.addOverlay(this.overlays.locationMarker);
+ }
+ }
+ }
+
+ // 实时更新方向(降低阈值到1度,保持实时性)
+ const headingChanged = !this.lastHeading || Math.abs(this.state.currentHeading - this.lastHeading) >= 1;
+
+ if (headingChanged) {
+ const oldHeading = this.lastHeading;
+ this.lastHeading = this.state.currentHeading;
+
+ // 实时更新图标(使用requestAnimationFrame确保平滑)
+ requestAnimationFrame(() => {
+ this.createRotatedLocationIcon(this.state.currentHeading).then((icon) => {
+ if (this.overlays.locationMarker) {
+ // 优先使用setIcon更新(不删除重建)
+ if (typeof this.overlays.locationMarker.setIcon === 'function') {
+ this.overlays.locationMarker.setIcon(icon);
+ } else {
+ // 如果不支持setIcon,需要重新创建(但保持位置)
+ const currentPoint = this.overlays.locationMarker.getPosition() || point;
+ this.map.removeOverlay(this.overlays.locationMarker);
+ this.overlays.locationMarker = new BMapGL.Marker(currentPoint, { icon });
+ this.map.addOverlay(this.overlays.locationMarker);
+ }
+ }
+ }).catch((error) => {
+ console.error('更新定位图标失败:', error);
+ // 恢复旧的方向值
+ this.lastHeading = oldHeading;
+ });
+ });
+ }
+ } catch (e) {
+ // 如果更新失败,重新创建标记
+ console.warn('更新标记失败,重新创建:', e);
+ try {
+ this.map.removeOverlay(this.overlays.locationMarker);
+ } catch (e2) {
+ // 忽略移除错误
+ }
+ this.overlays.locationMarker = null;
+ this._createNewMarker(point);
}
+ } else {
+ // 标记不存在,创建新标记
+ this._createNewMarker(point);
+ }
+ },
- // 创建新标记
+ /**
+ * 创建新的定位标记
+ */
+ _createNewMarker(point) {
+ this.createRotatedLocationIcon(this.state.currentHeading).then((icon) => {
this.overlays.locationMarker = new BMapGL.Marker(point, { icon });
this.map.addOverlay(this.overlays.locationMarker);
+ this.lastHeading = this.state.currentHeading;
}).catch((error) => {
console.error('创建定位图标失败:', error);
});
@@ -1546,6 +1626,12 @@
this.state.watchLocationTimer = null;
}
+ // 清理更新标记的定时器
+ if (this.updateMarkerTimer !== null) {
+ cancelAnimationFrame(this.updateMarkerTimer);
+ this.updateMarkerTimer = null;
+ }
+
// 清理百度地图定位实例
if (this.baiduGeolocation) {
this.baiduGeolocation = null;