import { TripsLayer } from '@deck.gl/geo-layers'; import type { Layer } from '@deck.gl/core'; import type { ProcessedTrack } from '../model/track.types'; import { getShipKindColor } from '../lib/adapters'; import { TRACK_REPLAY_LAYER_IDS } from './trackLayers'; import { DEPTH_DISABLED_PARAMS } from '../../../widgets/map3d/constants'; interface ReplayTrip { vesselId: string; path: [number, number][]; timestamps: number[]; color: [number, number, number, number]; } function toReplayTrips(tracks: ProcessedTrack[]): ReplayTrip[] { const out: ReplayTrip[] = []; for (const track of tracks) { if (!track.geometry.length || !track.timestampsMs.length) continue; const baseTime = track.timestampsMs[0]; out.push({ vesselId: track.vesselId, path: track.geometry, timestamps: track.timestampsMs.map((ts) => ts - baseTime), color: getShipKindColor(track.shipKindCode), }); } return out; } export function createReplayTrailLayer(options: { tracks: ProcessedTrack[]; currentTime: number; showTrail: boolean; }): Layer | null { const { tracks, currentTime, showTrail } = options; if (!showTrail || tracks.length === 0) return null; const trips = toReplayTrips(tracks); if (trips.length === 0) return null; const minBaseTime = Math.min(...tracks.map((track) => track.timestampsMs[0] || 0)); const relativeCurrentTime = Math.max(0, currentTime - minBaseTime); return new TripsLayer({ id: TRACK_REPLAY_LAYER_IDS.TRAIL, data: trips, getPath: (d) => d.path, getTimestamps: (d) => d.timestamps, getColor: (d) => d.color, currentTime: relativeCurrentTime, trailLength: 1000 * 60 * 60, fadeTrail: true, widthMinPixels: 2, widthMaxPixels: 4, capRounded: true, jointRounded: true, parameters: DEPTH_DISABLED_PARAMS, pickable: false, }); }