import { useEffect, useState } from "react"; import { Coordinates, Track } from "@mt/common-types"; import { getDistance, getPointDeviation } from "../utils"; const APPROXIMATE_DISTANCE = 15; // [meters] half of tramway length (~30 meters) export function usePassedTrackIndex( track: Track | null, currentPosition: Coordinates | null ) { const [passedTrackIndex, setPassedTrackIndex] = useState(0); useEffect(() => { if (!track || !currentPosition) { return; } let minDistance = getDistance(track[0], currentPosition); let newPassedIndex = 0; for (let i = 1; i < track.length; i++) { const distance = getDistance(track[i], currentPosition); if (distance < minDistance) { newPassedIndex = i; minDistance = distance; } } /** * Is current position more than APPROXIMATE_DISTANCE far from found track point * we need to check that we really reach newPassedIndex. If not — should decrement index */ if ( getDistance(track[newPassedIndex], currentPosition) > APPROXIMATE_DISTANCE ) { const prevIndex = Math.max(newPassedIndex - 1, 0); const nextIndex = Math.min(newPassedIndex + 1, track.length - 1); const leftDeviation = getPointDeviation( track[prevIndex], track[newPassedIndex], // Ближайшая точка трека currentPosition ); const rightDeviation = getPointDeviation( track[newPassedIndex], // Ближайшая точка трека track[nextIndex], currentPosition ); if (leftDeviation >= rightDeviation) { newPassedIndex--; } } setPassedTrackIndex(newPassedIndex); }, [track, currentPosition]); return { passedTrackIndex }; }