WhiteNightsAdminPanel/src/preview/components/MapWidget/hooks/usePassedTrackIndex.ts
2025-04-15 21:12:43 +03:00

62 lines
1.7 KiB
TypeScript

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<number>(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 };
}