| | |
| | | convertAdcodeToCityCode, |
| | | getCityInfoWithId, |
| | | getDistance, |
| | | getProjectedPoint, |
| | | mapOrderStatusToTripStatus, |
| | | reportEvent |
| | | } from '../../../utils/Robotaxi-public-method'; |
| | |
| | | // 使用 eraseLines 擦除已行驶路段(状态4/6专用) |
| | | const erasePassedRouteSegments = (newPoints: any[], served?: number) => { |
| | | const oldPoints = currentFullRouteRef.current; |
| | | if (!oldPoints?.length || !newPoints?.length) return; |
| | | if (!oldPoints?.length || !newPoints?.length) return newPoints?.[0]; |
| | | |
| | | const newFirst = newPoints[0]; |
| | | let bestMatchIndex = -1; |
| | | let bestDistance = Infinity; |
| | | const startIndex = lastErasedIndexRef.current; |
| | | |
| | | // 如果后端提供了明确的已行驶点数 served (作为增量:这次少了几个点) |
| | | if (typeof served === 'number' && !Number.isNaN(served) && served > 0) { |
| | | // 既然 served 是这次少了多少个点,那么新的擦除索引 = 上次的索引 + served |
| | | if (typeof served === 'number' && !Number.isNaN(served) && served >= 0) { |
| | | bestMatchIndex = startIndex + served; |
| | | // 确保不超过数组范围 |
| | | bestMatchIndex = Math.min(bestMatchIndex, oldPoints.length - 1); |
| | | } else { |
| | | let bestDistance = Infinity; |
| | | // 降级使用距离匹配逻辑,移除不合理的退出条件,使匹配更加敏感 |
| | | for (let i = startIndex; i < oldPoints.length; i++) { |
| | | const dist = getDistance( |
| | |
| | | // 如果找到了非常近的点(例如10米内),就可以认为这就是车辆当前位置所在的索引,提前结束查找 |
| | | if (bestDistance < 10) break; |
| | | } |
| | | } |
| | | |
| | | if (bestMatchIndex < startIndex) { |
| | | // 路线发生较大变化,回退为全量重绘 |
| | | currentFullRouteRef.current = [...newPoints]; |
| | | lastErasedIndexRef.current = 0; |
| | | lastRoutePointRef.current = null; |
| | | lastRouteUpdateAtRef.current = 0; |
| | | setRoutePoints([...newPoints]); |
| | | return newPoints[0]; |
| | | } |
| | | |
| | | // 只要找到了比之前更大的索引,就进行擦除(无论距离多远,只要是往后走就应该擦除) |
| | |
| | | }); |
| | | |
| | | lastErasedIndexRef.current = bestMatchIndex; |
| | | } else { |
| | | // 路线发生较大变化,回退为全量重绘 |
| | | currentFullRouteRef.current = [...newPoints]; |
| | | lastErasedIndexRef.current = 0; |
| | | lastRoutePointRef.current = null; |
| | | lastRouteUpdateAtRef.current = 0; |
| | | setRoutePoints([...newPoints]); |
| | | } |
| | | |
| | | const nextIndex = Math.min(bestMatchIndex + 1, oldPoints.length - 1); |
| | | const pointA = oldPoints[bestMatchIndex]; |
| | | const pointB = oldPoints[nextIndex]; |
| | | |
| | | return getProjectedPoint(newFirst, pointA, pointB); |
| | | }; |
| | | |
| | | // 更新车辆位置(移除节流,实时更新) |
| | |
| | | // 状态4/6:使用 eraseLines 擦除已行驶路段,不再全量重绘 |
| | | const isEraseStatus = [4, 6].includes(tripStatusRef.current); |
| | | if (isEraseStatus) { |
| | | const firstPoint = points?.[0]; |
| | | let vehiclePoint = points?.[0]; |
| | | if (orderRouteInitializedRef.current && currentFullRouteRef.current.length > 0) { |
| | | // 后续更新:擦除已行驶路段 |
| | | let servedCount = 0; |
| | |
| | | } catch (e) { |
| | | console.error('解析 served 数据失败', e); |
| | | } |
| | | erasePassedRouteSegments(points, servedCount); |
| | | vehiclePoint = erasePassedRouteSegments(points, servedCount) || points?.[0]; |
| | | } else { |
| | | // 首次绘制:全量渲染并存储完整路线 |
| | | orderRouteInitializedRef.current = true; |
| | |
| | | applyRoutePoints(points); |
| | | }); |
| | | } |
| | | if (firstPoint && typeof firstPoint.latitude === 'number' && typeof firstPoint.longitude === 'number') { |
| | | updateVehicleLocationThrottled(firstPoint.latitude, firstPoint.longitude, true); |
| | | if (vehiclePoint && typeof vehiclePoint.latitude === 'number' && typeof vehiclePoint.longitude === 'number') { |
| | | updateVehicleLocationThrottled(vehiclePoint.latitude, vehiclePoint.longitude, true); |
| | | } |
| | | return; |
| | | } |