图标定位修改

This commit is contained in:
cwchen 2026-01-14 14:53:05 +08:00
parent 019a54d5dd
commit 6a6c6b1ac5
1 changed files with 100 additions and 14 deletions

View File

@ -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;