| | |
| | | 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'; |
| | | |
| | |
| | | }; |
| | | |
| | | /** |
| | | * 车辆已到(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), |