liaofang
2026-08-14 9f458cd69508026b10eca1145f4e69d5bdf9c98e
refactor(camera): 优化车辆已到上车点相机策略

- 修改车辆已到意图为聚焦上车点并居中至可视区域,避免使用包含用户定位的 fit 策略
- 取消车辆、用户、上车点三点 fit,解决旧用户定位导致视口撑歪问题
- 添加缺失车辆坐标时返回无意图处理逻辑
- 注释中详细说明调整原因和实现细节
- 取消调试模拟器入口的注释限制,便于开发调试
2个文件已修改
50 ■■■■■ 已修改文件
src/robotaxi/pages/begin-route/hooks/camera/policies/pickup.policy.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/index.tsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/robotaxi/pages/begin-route/hooks/camera/policies/pickup.policy.ts
@@ -1,5 +1,5 @@
import { CameraContext, CameraIntent, CameraPolicy, NO_CAMERA_INTENT } from '../camera-policy.types';
import { LatLng, buildPointsSignature } from '../map-camera';
import { buildPointsSignature } from '../map-camera';
import { collectPickupViewportPoints, siteToPoint } from '../collect-viewport-points';
import { mapPerfLog } from '../map-perf-log';
@@ -47,44 +47,38 @@
};
/**
 * 车辆已到(VehicleArrivedPickup) 意图:fit 车 + 用户 + 上车点 (viewport:'car_user')。
 * 车辆位置缺失时用上车点兜底(车已到,二者接近);点不足 2 个则 focus 单点。
 * 车辆已到(VehicleArrivedPickup) 意图:focus 上车点(车已到,二者接近),
 * centerInVisibleArea 居中到扣除底部卡片后的可视区域。
 *
 * 不使用 fit(includePoints):
 * 1. 不使用 userLocation——到达上车点时用户定位仍是页面进入时的旧值,会把视口撑歪
 *    (与 arrivedDestinationPolicy 同理);
 * 2. 车+用户+上车点三点极近时 includePoints 不理会不对称 padding,会把点放到
 *    整张地图几何中心(视觉上贴近底部卡片),与 callingPolicy 注释同理。
 * 改用 focus + centerInVisibleArea:与 callingPolicy 一致,精确居中到可视区域。
 */
const buildArrivedPickupIntent = (ctx: CameraContext, stable: boolean): CameraIntent => {
  const vehicleRaw = siteToPoint(ctx.vehicleLocation);
  const pickup = siteToPoint(ctx.startSite);
  const car = vehicleRaw || pickup; // 车辆坐标校验,缺失用上车点兜底
  const points: LatLng[] = [];
  if (car) points.push(car);
  const user = siteToPoint(ctx.userLocation);
  if (user) points.push(user);
  // 上车点始终纳入 fit(三点:车 + 用户 + 上车点),避免车辆已偏离上车点位置时
  // 上车点被推出可视区域;car 用上车点兜底时该点会与 car 重合,includePoints 对
  // 重复点安全,不影响结果。
  if (pickup) points.push(pickup);
  // 调试日志:车辆到达上车点时打印三点各自是否取到及坐标,便于排查视口未居中问题。
  // includePoints 实际使用的 padding 值由 MapCamera.fit 内的 'fit:exec' 日志打印
  // (signature 同为 'arrived-pickup',可按签名关联两条日志)。
  mapPerfLog('policy:arrived-pickup-points', {
    stable,
    car: { got: !!vehicleRaw, usedPickupFallback: !vehicleRaw && !!pickup, point: car },
    user: { got: !!user, point: user },
    pickup: { got: !!pickup, point: pickup },
    fitPointsCount: points.length,
  });
  if (points.length >= MIN_FIT_POINTS) {
    return {
      type: 'fit',
      points,
      signature: stable ? 'arrived-pickup' : undefined,
    };
  if (!car) {
    return NO_CAMERA_INTENT;
  }
  // 只有车(无用户定位、无上车点):居中到车
  return car ? { type: 'focus', point: car } : NO_CAMERA_INTENT;
  return {
    type: 'focus',
    point: car,
    centerInVisibleArea: true,
    signature: stable ? 'arrived-pickup' : undefined,
  };
};
/**
 * 车辆已到上车点相机策略:把车+用户+上车点三点居中一次;手势后空闲回中。
 * 车辆已到上车点相机策略:focus 上车点到可视区域中心;手势后空闲回中。
 */
export const arrivedPickupPolicy: CameraPolicy = {
  onInitial: (ctx) => buildArrivedPickupIntent(ctx, true),
src/robotaxi/pages/begin-route/index.tsx
@@ -10,7 +10,7 @@
import PickupExceptionPopup from './components/pickup-exception-popup';
import CreditPayPopup from './components/credit-pay-popup';
// 调试面板:模拟完整行程流转(仅 dev 构建可见)
// import DebugOrderSimulatorPanel from './components/debug-order-simulator-panel';
import DebugOrderSimulatorPanel from './components/debug-order-simulator-panel';
// 转场动效调试面板:呼叫中→派单成功、送驾中→行程结束(仅 dev 构建可见)
// import DebugTransitionPanel from './components/debug-transition-panel';
// 到达结束态全屏礼花动效
@@ -2683,7 +2683,7 @@
        setTripStatus={setTripStatus}
        bindSocketListeners={bindSocketListeners}
      /> */}
      {/* 模拟器入口已关闭,如需本地调试可取消下方注释
      {/* 模拟器入口已关闭,如需本地调试可取消下方注释 */}
      <DebugOrderSimulatorPanel
        orderId={orderId}
        setOrderId={setOrderId}
@@ -2695,7 +2695,7 @@
        setShowCancelPopup={setShowCancelPopup}
        setShowModifyDestinationFailPopup={setShowModifyDestinationFailPopup}
        setModifyDestinationFailMessage={setModifyDestinationFailMessage}
      />*/}
      />
    </>
  )