|
@@ -474,13 +474,13 @@ const addRealtimePoint = async (pt: {
|
|
|
const lat = Number(pt.latitude)
|
|
const lat = Number(pt.latitude)
|
|
|
if (!Number.isFinite(lng) || !Number.isFinite(lat)) return
|
|
if (!Number.isFinite(lng) || !Number.isFinite(lat)) return
|
|
|
|
|
|
|
|
- // 去重:与最后一点相同则忽略
|
|
|
|
|
- const last = historyPoints[historyPoints.length - 1]
|
|
|
|
|
- const lastKey = last
|
|
|
|
|
- ? `${Number(last.longitude).toFixed(6)},${Number(last.latitude).toFixed(6)}`
|
|
|
|
|
|
|
+ // 去重:与最新一点相同则忽略(最新在第一位)
|
|
|
|
|
+ const first = historyPoints[0]
|
|
|
|
|
+ const firstKey = first
|
|
|
|
|
+ ? `${Number(first.longitude).toFixed(6)},${Number(first.latitude).toFixed(6)}`
|
|
|
: ''
|
|
: ''
|
|
|
const curKey = `${lng.toFixed(6)},${lat.toFixed(6)}`
|
|
const curKey = `${lng.toFixed(6)},${lat.toFixed(6)}`
|
|
|
- if (lastKey && lastKey === curKey) return
|
|
|
|
|
|
|
+ if (firstKey && firstKey === curKey) return
|
|
|
|
|
|
|
|
// 确保地图存在
|
|
// 确保地图存在
|
|
|
ensureMap(lng, lat)
|
|
ensureMap(lng, lat)
|
|
@@ -494,19 +494,19 @@ const addRealtimePoint = async (pt: {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 保存到历史(带地址)
|
|
|
|
|
|
|
+ // 保存到历史(带地址)——追加到第一位
|
|
|
const rec: HistoryPoint = {
|
|
const rec: HistoryPoint = {
|
|
|
longitude: lng,
|
|
longitude: lng,
|
|
|
latitude: lat,
|
|
latitude: lat,
|
|
|
locationTime: pt.locationTime,
|
|
locationTime: pt.locationTime,
|
|
|
address: addressCache[curKey] || ''
|
|
address: addressCache[curKey] || ''
|
|
|
}
|
|
}
|
|
|
- historyPoints.push(rec)
|
|
|
|
|
|
|
+ historyPoints.unshift(rec)
|
|
|
|
|
|
|
|
const AMap = (window as any).AMap
|
|
const AMap = (window as any).AMap
|
|
|
if (!AMap || !AMap.Marker) return
|
|
if (!AMap || !AMap.Marker) return
|
|
|
|
|
|
|
|
- // 添加标记
|
|
|
|
|
|
|
+ // 添加标记(同步到第一位)
|
|
|
const marker = new AMap.Marker({
|
|
const marker = new AMap.Marker({
|
|
|
position: [lng, lat],
|
|
position: [lng, lat],
|
|
|
title: rec.locationTime ? `时间:${rec.locationTime}` : `实时点位`
|
|
title: rec.locationTime ? `时间:${rec.locationTime}` : `实时点位`
|
|
@@ -516,12 +516,35 @@ const addRealtimePoint = async (pt: {
|
|
|
} else if (amap && typeof amap.addOverlays === 'function') {
|
|
} else if (amap && typeof amap.addOverlays === 'function') {
|
|
|
amap.addOverlays([marker])
|
|
amap.addOverlays([marker])
|
|
|
}
|
|
}
|
|
|
- markers.push(marker)
|
|
|
|
|
|
|
|
|
|
- // 限制最多100条,同时删除最早的覆盖物
|
|
|
|
|
|
|
+ // 绑定信息窗
|
|
|
|
|
+ try {
|
|
|
|
|
+ const infoContent = `<div style="padding:8px 10px;font-size:12px;color:#000;">
|
|
|
|
|
+ <div><strong>实时定位</strong></div>
|
|
|
|
|
+ ${rec.locationTime ? `<div>时间:${rec.locationTime}</div>` : ''}
|
|
|
|
|
+ ${rec.address ? `<div>地点:${rec.address}</div>` : ''}
|
|
|
|
|
+ <div>经度:${lng.toFixed(6)},纬度:${lat.toFixed(6)}</div>
|
|
|
|
|
+ </div>`
|
|
|
|
|
+ if (AMap.InfoWindow) {
|
|
|
|
|
+ const info = new AMap.InfoWindow({
|
|
|
|
|
+ content: infoContent,
|
|
|
|
|
+ offset: new AMap.Pixel(0, -30)
|
|
|
|
|
+ })
|
|
|
|
|
+ marker.on &&
|
|
|
|
|
+ marker.on('click', () => {
|
|
|
|
|
+ if (amap) info.open(amap, marker.getPosition())
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.warn('实时点信息窗创建失败(忽略):', err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ markers.unshift(marker)
|
|
|
|
|
+
|
|
|
|
|
+ // 限制最多100条,同时删除最晚的覆盖物(尾部)
|
|
|
if (historyPoints.length > 100) {
|
|
if (historyPoints.length > 100) {
|
|
|
- historyPoints.shift()
|
|
|
|
|
- const removed = markers.shift()
|
|
|
|
|
|
|
+ historyPoints.pop()
|
|
|
|
|
+ const removed = markers.pop()
|
|
|
try {
|
|
try {
|
|
|
if (removed) {
|
|
if (removed) {
|
|
|
if (typeof amap.remove === 'function') amap.remove(removed)
|
|
if (typeof amap.remove === 'function') amap.remove(removed)
|
|
@@ -533,9 +556,8 @@ const addRealtimePoint = async (pt: {
|
|
|
// 更新轨迹与右侧列表
|
|
// 更新轨迹与右侧列表
|
|
|
updatePolyline()
|
|
updatePolyline()
|
|
|
syncDisplayPoints()
|
|
syncDisplayPoints()
|
|
|
- scrollListToBottom()
|
|
|
|
|
|
|
|
|
|
- // 适配视野或居中到最新点
|
|
|
|
|
|
|
+ // 将视野适配到轨迹或居中到最新点
|
|
|
try {
|
|
try {
|
|
|
if (amap?.setFitView && polyline) {
|
|
if (amap?.setFitView && polyline) {
|
|
|
amap.setFitView([polyline, ...markers])
|
|
amap.setFitView([polyline, ...markers])
|