useUpdateAllTrainCarsCoordinates.tsx
unknown
plain_text
2 years ago
6.1 kB
7
Indexable
import {useEffect, useMemo, useRef} from 'react'; import {useSelector, useDispatch} from 'react-redux'; import GetLocation from 'react-native-get-location'; import {getConsistTrain} from '@Redux/train/selectors'; import { getRunningStatus, getUseSimulatedTestData, getUseTestData, } from '@Redux/common/selectors'; import {getTrackGroupData} from '@Redux/track/selectors'; import { setAllTrainCarsInfo, setAngle, setPosition, setLocationData, getLiveDemoData, setTrainLineData, } from '@Redux/info/actions'; import {setOutOfTrack} from '@Redux/common/actions'; import {getLocationData} from '@Redux/info/selectors'; import {getAngle} from '@Utils/getCorridorSegmentDetails'; import {getTrainCarsDetails, getLineEndCoord} from '@Utils/computeTrainData'; import {getDistanceToTrack} from '@Utils/geometryHelper'; import {getCleanedGpsPoint} from '@Utils/cleanGpsData'; import {generateSimulatedGpsPoints} from '@Utils/simulationModeHelper'; import { DEFAULT_LOCOMOTIVE_LENGTH_IN_MILES, DEFAULT_RAIL_CAR_LENGTH_IN_MILES, FT_TO_MILE, SNAP_TO_TRACK_DISTANCE, } from '@Constants'; const useUpdateAllTrainCarsCoordinates = ( trackCoords: any[][], track: any[], currentTripKey: string, ) => { const dispatch = useDispatch(); const runningStatus = useSelector(getRunningStatus); const useTestData = useSelector(getUseTestData); const useSimulatedTestData = useSelector(getUseSimulatedTestData); const trackGroupData = useSelector(state => getTrackGroupData(state)); const speedLimitList = trackGroupData[currentTripKey]?.data?.trackSpeedLimit || []; const absoluteStartTrackDistanceMiles = (track?.length > 0 && track[0]?.absoluteStartTrackDistanceMiles) || 0; const simulatedLocationData = useTestData ? useMemo( () => generateSimulatedGpsPoints( track, trackCoords, speedLimitList, absoluteStartTrackDistanceMiles, ), [track, trackCoords], ) : null; const locationData = useSelector(state => getLocationData(state)); // Get consist data and create train cars info const consistTrain = useSelector(getConsistTrain); const trainLengthInFt = consistTrain?.totalLengthFt || 0; const trainLengthInMiles = trainLengthInFt * FT_TO_MILE; const locomotiveCount = consistTrain?.locomotiveCount || 1; const locomotivesLengthInMiles = locomotiveCount * DEFAULT_LOCOMOTIVE_LENGTH_IN_MILES; const trainCarsInfo: any = useMemo(() => { const locomotiveList = [...Array(consistTrain?.locomotiveCount || 0)].map( () => ({ type: 'locomotive', carLengthInMiles: DEFAULT_LOCOMOTIVE_LENGTH_IN_MILES, }), ); const carList = [...Array(consistTrain?.carCount || 0)].map(() => ({ type: 'car', carLengthInMiles: DEFAULT_RAIL_CAR_LENGTH_IN_MILES, })); return [...locomotiveList, ...carList]; }, [consistTrain]); const processTrainData = (location: any) => { const deviceCoord = [location.latitude, location.longitude]; const withinSnapToTrackDistance = getDistanceToTrack(deviceCoord, trackCoords) <= SNAP_TO_TRACK_DISTANCE; // Apply cleaning algorithm if applicable if (withinSnapToTrackDistance) { const cleanCoord = getCleanedGpsPoint(deviceCoord, trackCoords); const angle = getAngle(cleanCoord, trackCoords); // Then compute start and end coordinates of train line const trainLineData = { locoStartCoord: cleanCoord, locoEndCoord: getLineEndCoord( cleanCoord, locomotivesLengthInMiles, trackCoords, ), trainEndCoord: getLineEndCoord( cleanCoord, trainLengthInMiles, trackCoords, ), }; // Then compute info (coordinates, angle) of all train cars const updatedTrainCarsInfo = [ { ...trainCarsInfo[0], coord: cleanCoord, angle, }, ...trainCarsInfo.slice(1), ]; const newTrainCarsInfo = getTrainCarsDetails( updatedTrainCarsInfo, trackCoords, ); dispatch(setTrainLineData(trainLineData)); dispatch(setAllTrainCarsInfo(newTrainCarsInfo)); dispatch(setPosition(cleanCoord)); dispatch(setAngle(angle)); dispatch(setOutOfTrack(false)); } else { dispatch(setPosition(deviceCoord)); dispatch(setAngle(null)); dispatch(setOutOfTrack(true)); } }; // Get location data from device const getDeviceLocationData = () => { try { GetLocation.getCurrentPosition({ enableHighAccuracy: true, timeout: 15000, }) .then(location => { dispatch(setLocationData(location)); processTrainData(location); }) .catch(error => { console.log(error?.message || ''); }); } catch (error: any) { console.log(error?.message || ''); } }; const locationIndex = useRef(0); const getSimulatedLocationData = () => { if (!simulatedLocationData) { return; } if (!runningStatus) { return; } if (locationIndex.current > simulatedLocationData.length - 1) { return; } const location = simulatedLocationData[locationIndex.current]; dispatch(setLocationData(location)); processTrainData(location); locationIndex.current++; }; const getLiveSimulatedLocationData = () => { dispatch(getLiveDemoData()); }; useEffect(() => { if (locationData && useSimulatedTestData) { processTrainData(locationData); } }, [locationData]); useEffect(() => { locationIndex.current = 0; let interval = setInterval(() => { if (useTestData) { getSimulatedLocationData(); } else if (useSimulatedTestData) { getLiveSimulatedLocationData(); } else { getDeviceLocationData(); } }, 1000); return () => { clearInterval(interval); }; }, [currentTripKey, runningStatus]); }; export default useUpdateAllTrainCarsCoordinates;
Editor is loading...