Map/InfoCar/index.tsx
unknown
plain_text
2 years ago
31 kB
6
Indexable
/* eslint-disable react-native/no-inline-styles */ import React, {useEffect, useRef, useState, useMemo} from 'react'; import { Text, View, TouchableOpacity, Animated, useWindowDimensions, } from 'react-native'; import GetLocation from 'react-native-get-location'; import isEmpty from 'lodash/isEmpty'; import dayjs from 'dayjs'; // Navigation import {useNavigation} from '@react-navigation/native'; import ScreensName from '@Configs/navigator'; // Redux Selectors import {useSelector, useDispatch} from 'react-redux'; import { getRunningTrains, getCurrentTripKey, getTripId, getStationHistory, getSimpleTrainConsistSelector, } from '@Redux/trip/selectors'; import {getLocationData, getPosition} from '@Redux/info/selectors'; import {getModels} from '@Redux/model/selectors'; import { getWaitingStatus, getRunningStatus, getFinishedStatus, getTravelDistance, getOrientation, getActiveEnv, getOutOfTrack, getUserInteractTime, getShowTrackGradeView, getCurrentMilepost, getLastTimeFinishedChanged, } from '@Redux/common/selectors'; import {getUserAuthorizationSelector, getUsername} from '@Redux/auth/selectors'; import {getInstructionGroup} from '@Redux/instruction/selectors'; import {getStopStations, getTrackGroupData} from '@Redux/track/selectors'; import { getSelectedTrainId, getTrainSelectionInfo, } from '@Redux/train/selectors'; import {getMultipleSpeedProfileList} from '@Redux/speedProfile/selectors'; import {getConsistTrain, getCurrentSpeed} from '@Redux/train/selectors'; import {getStationActive} from '@Redux/station/selectors'; // Redux Actions import { setRunning, setFinished, setWaiting, setTravelDistance, } from '@Redux/common/actions'; import { setGpsItem, setCurrentTripKey, cleanGpsList, clearModelEventList, setModelEventItem, setStartStationHistory, setEndStationHistory, addStationHistoryItem, addSpeedHistoryItem, } from '@Redux/trip/actions'; import {clearInstructionGroup} from '@Redux/instruction/actions'; // Components import Loader from './Loader'; import RightWidget from './RightWidget'; import ETA from './ETA'; import RecommendationItem from './RecommendationItem/RecommendationItem'; import Recenter from '@Com/Recenter'; import CloseTrip from './CloseTrip'; import ZoomInOut from '@Com/ZoomInOut'; import TrackGradeView from '@Com/TrackGradeView'; import ScaleBar from '@Com/ScaleBar'; import Speedometer from '@Com/Speedometer'; // Constants import { END_TRIP_ON_ARRIVE_AFTER_SECONDS, TRAIN_IMAGE_WIDTH_BY_KM, } from '@Constants'; // Types import {UseStateTuple, Region} from '@Types'; import {ModelEventType} from '@Types'; // Utils import {modelInterface} from '@Utils/modelInterface'; import {filterInterface} from '@Utils/filterInterface'; import { getOffsetCoordinate, getBearingAngle, haversineDistance, } from '@Utils/geometryHelper'; import {getSegmentIdFromCoord} from '@Utils/getCorridorSegmentDetails'; import { createNewGPSFile, generateGPSFileName, generateGpsData, } from '@Utils/gpsData'; import { generateModelFileName, createNewModelFile, appendToModelFile, } from '@Utils/modelData'; // Hooks import useLogGPSLocation from '@Hooks/useLogGPSLocation'; // Styles import styles from './styles'; const ModelInterface = new modelInterface(); export type MapProps = { region?: Region; }; const InfoCar: React.FC<{ mapRef: any; regionRef: any; isReady: boolean; }> = ({mapRef, regionRef, isReady}) => { const {width, height: screenHeight} = useWindowDimensions(); const dispatch = useDispatch(); const navigation = useNavigation(); const currentAngleRef = useRef(); const currentTravelDistance = useRef(0); const [totalDistanceBase, setTotalDistanceBase]: UseStateTuple<number> = useState(0); const trains = useSelector(state => getRunningTrains(state)); const orientation = useSelector(state => getOrientation(state)); const envName = useSelector(state => getActiveEnv(state)); const height = envName === 'production' ? screenHeight : screenHeight - 25; const models = useSelector(state => getModels(state)); const runningStatus = useSelector(state => getRunningStatus(state)); const waitingStatus = useSelector(state => getWaitingStatus(state)); const finishedStatus = useSelector(state => getFinishedStatus(state)); const lastTimeFinishedChanged = useSelector(state => getLastTimeFinishedChanged(state), ); const isOutOfTrack = useSelector(state => getOutOfTrack(state)); const selectedTrainId = useSelector(state => getSelectedTrainId(state)); const currentMilePost = useSelector(getCurrentMilepost); const position = useSelector(state => getPosition(state)); const location = useSelector(state => getLocationData(state)); const travelDistance = useSelector(state => getTravelDistance(state)); const instructionGroup = useSelector(state => getInstructionGroup(state)); const stopStations = useSelector(state => getStopStations(state)); const currentTripKey = useSelector(state => getCurrentTripKey(state)); const trackGroupData = useSelector(state => getTrackGroupData(state)); const tripId = useSelector(state => getTripId(state)); const username = useSelector(state => getUsername(state)); const userAuthorization = useSelector(state => getUserAuthorizationSelector(state), ); const trainSelectionInfo = useSelector(state => getTrainSelectionInfo(state)); const simpleTrainConsist = useSelector(state => getSimpleTrainConsistSelector(state), ); const stationHistory = useSelector(state => getStationHistory(state)); const multipleSpeedProfile = useSelector(state => getMultipleSpeedProfileList(state), ); const userInteractTime = useSelector(state => getUserInteractTime(state)); const showTrackGradeView = useSelector(getShowTrackGradeView); const activeStation = useSelector(getStationActive); const consistTrain = useSelector(getConsistTrain); const currentSpeed = useSelector(getCurrentSpeed); let speedProfile = []; if (currentTripKey && !isEmpty(multipleSpeedProfile)) { if (typeof multipleSpeedProfile[currentTripKey] !== 'undefined') { speedProfile = multipleSpeedProfile[currentTripKey]?.data || []; } } const corridorList: any[] = useMemo(() => { if (currentTripKey && !isEmpty(trackGroupData)) { if (typeof trackGroupData[currentTripKey] !== 'undefined') { return trackGroupData[currentTripKey]?.data?.corridors || []; } else { return []; } } else { return []; } }, [trackGroupData, currentTripKey]); let instructions = []; if (currentTripKey && !isEmpty(instructionGroup)) { if (typeof instructionGroup[currentTripKey] !== 'undefined') { instructions = instructionGroup[currentTripKey]?.data || []; } } const [count, setCount] = useState(0); const [gpsJsonFileName, setGPSJsonFileName]: UseStateTuple<string | any> = useState(null); const [modelJsonFileName, setModelJsonFileName]: UseStateTuple<string | any> = useState(null); const [arriveTime, setArriveTime]: UseStateTuple<any> = useState(null); const opacityRef = useRef(new Animated.Value(1)).current; const trackingTrainId = isEmpty(selectedTrainId) ? 'none' : selectedTrainId; const [zoomScale, setZoomScale]: UseStateTuple<number> = useState(0); const [cameraCenter, setCameraCenter]: UseStateTuple<any> = useState(null); const [prevZoomScale, setPrevZoomScale]: UseStateTuple<number> = useState(0); const [loading, setLoading]: UseStateTuple<boolean> = useState(true); const [startAngle, setStartAngle]: UseStateTuple<number> = useState(0); const [startPos, setStartPos]: UseStateTuple<any> = useState(); const [timerCheck, setTimerCheck]: UseStateTuple<number> = useState(0); const [confirmArrived, setConfirmArrived]: UseStateTuple<boolean> = useState(false); const [currentRecommendation, setCurrentRecommendation]: UseStateTuple<any> = useState(null); const [ incomingRecommendation, setIncomingRecommendation, ]: UseStateTuple<any> = useState(null); const corridorListFilter = useMemo( () => corridorList.map((item: any) => { return [ item.gpsCoordinates.lat, item.gpsCoordinates.lng, item.corridor, item.station, item.stn1x, item.stn2x, item.distanceToNext, item.milepost, ]; }), [corridorList], ); const sortInstruction = instructions.sort((a: any, b: any) => { return a.startMile - b.startMile; }); const nextInstructionIndex = sortInstruction.findIndex((item: any) => { return item.startMile > travelDistance; }); const filterSpeedProfile = speedProfile.sort( (a, b) => a?.distance - b?.distance, ); const currentSpeedProfleValueIndex = filterSpeedProfile.findIndex(item => { return item?.distance >= travelDistance; }); const currentSpeedProfleValue = currentSpeedProfleValueIndex >= 0 ? filterSpeedProfile[currentSpeedProfleValueIndex] : filterSpeedProfile[filterSpeedProfile.length - 1]; const estimatedTimeWithSpeedProfile = useMemo(() => { let timeToArrival; if (Number.isNaN(currentSpeedProfleValue?.estimatedDurationToArrival)) { timeToArrival = dayjs(); } else { timeToArrival = dayjs().add( currentSpeedProfleValue?.estimatedDurationToArrival, 'minute', ); } return timeToArrival.format('h:mma'); }, [currentSpeedProfleValue, timerCheck]); useEffect(() => { ModelInterface.loadAllModels(models); }, []); useEffect(() => { const timerInterval = setInterval(() => { setTimerCheck(prev => (prev += 1)); }, 60000); return () => { clearInterval(timerInterval); }; }, []); useEffect(() => { const trackGroupDataValues = Object.values(trackGroupData) || []; const firstTrackData = trackGroupDataValues.find(item => item.order === 0); if (firstTrackData) { setStartPos([ firstTrackData?.data?.corridors[0]?.gpsCoordinates.lat, firstTrackData?.data?.corridors[0]?.gpsCoordinates.lng, ]); } }, []); useEffect(() => { checkForZoomLevel(userInteractTime); }, [userInteractTime]); const checkForZoomLevel = async (numberCheck = 0) => { try { const camera = await mapRef.current?.getCamera(); if (numberCheck === 0 || !camera) { setZoomScale(13.5); } else { setZoomScale(camera.zoom); } } catch (error) { setZoomScale(13.5); console.log('setZoomScale Error', error); } }; const opacity = opacityRef.interpolate({ inputRange: [0, 1], outputRange: [0, 1], }); const closeLoader = () => { Animated.timing(opacityRef, { toValue: 0, duration: 500, useNativeDriver: true, }).start(() => { setLoading(false); }); }; const setCameraMap = async ( trainsSet: any, latitude: number, longitude: number, isGettingReady: boolean = false, ) => { let angleCarDefault = 90; const camera = await mapRef.current?.getCamera(); setCameraCenter(camera.center); if (!zoomScale) { setZoomScale(camera.zoom); } // if (zoomScale !== prevZoomScale) { // setPrevZoomScale(zoomScale); // hideTrain(); // } const offsetWithCorridor = getOffsetCoordinate( [latitude, longitude], TRAIN_IMAGE_WIDTH_BY_KM / 2, angleCarDefault + trainsSet[0].angle + 90, ); const offsetValue = (zoom: number) => { const isLandScape = orientation === 'landscape' ? true : false; if (zoom < 10.5) { return isLandScape ? 6 : 16; } switch (Math.floor(zoom)) { case 10: return isLandScape ? 4 : 10; case 11: return isLandScape ? 2 : 6; case 12: return isLandScape ? 1 : 3; case 13: if (zoom > 13.5) { return isLandScape ? 0.4 : 1.2; } return isLandScape ? 0.8 : 2; case 14: return isLandScape ? 0.25 : 0.6; case 15: return isLandScape ? 0.14 : 0.3; case 16: return isLandScape ? 0.07 : 0.2; case 17: return isLandScape ? 0.04 : 0.1; default: return 0; } }; let offsetWithCenter; if (runningStatus) { offsetWithCenter = getOffsetCoordinate( [offsetWithCorridor.latitude, offsetWithCorridor.longitude], isOutOfTrack ? 0 : offsetValue(zoomScale), angleCarDefault + trainsSet[0].angle, ); } else { offsetWithCenter = getOffsetCoordinate( [offsetWithCorridor.latitude, offsetWithCorridor.longitude], isOutOfTrack && !isGettingReady ? 0 : offsetValue(zoomScale), angleCarDefault + startAngle, ); } const autoCenterLocation = { latitude: offsetWithCenter.latitude, longitude: offsetWithCenter.longitude, }; let autoHeading = angleCarDefault + startAngle; if (runningStatus) { if (isOutOfTrack) { autoHeading = currentAngleRef.current ? currentAngleRef.current : angleCarDefault + startAngle; } else { autoHeading = angleCarDefault + trainsSet[0].angle; currentAngleRef.current = angleCarDefault + trainsSet[0].angle; } } else { autoHeading = angleCarDefault + startAngle; } // autoCenter // ? mapRef.current.animateCamera({ // ...camera, // zoom: zoomScale ? zoomScale : camera.zoom, // heading: autoCenter ? autoHeading : camera.heading, // center: autoCenter ? autoCenterLocation : camera.center, // }) // : null; /** * check Loading */ if (loading) { setTimeout(() => { closeLoader(); }, 3000); } }; useEffect(() => { if (loading) { setTimeout(() => { closeLoader(); }, 3000); } }, []); const processStopStations = useMemo(() => { return Object.values(stopStations).sort( (a: any, b: any) => a?.order - b?.order, ); }, [stopStations]); const setGpsDataToStore = () => { GetLocation.getCurrentPosition({ enableHighAccuracy: true, timeout: 15000, }) .then(location => { const gpsData = generateGpsData(location); if (runningStatus) { // if (regionRef.current?.latitude !== location.latitude) { dispatch(setGpsItem(gpsData)); // } } }) .catch(error => { const {code, message} = error; // console.warn(code, message); }); }; useEffect(() => { dispatch( addSpeedHistoryItem({ distance: travelDistance + totalDistanceBase, speed: currentSpeed, }), ); if (trackingTrainId === 'none') { return; } setGpsDataToStore(); }, [position]); // CHECK ARRIVED AT LAST STATION AND CLOSE THE TRIP useEffect(() => { const timeout = setTimeout(() => { setCount(count + 1); const currentTime = Math.floor(Date.now() / 1000); if ( finishedStatus && lastTimeFinishedChanged + END_TRIP_ON_ARRIVE_AFTER_SECONDS < currentTime ) { const stationPair = currentTripKey.split('-'); dispatch( setEndStationHistory({ stationId: stationPair[1], arrivedTimeStamp: new Date().toString(), departedTimeStamp: null, }), ); dispatch(setFinished(false)); dispatch(setWaiting(false)); dispatch(setRunning(false)); dispatch(clearInstructionGroup()); navigation.navigate(ScreensName.TRIP_REVIEW); } }, 5000); return () => clearTimeout(timeout); }, [finishedStatus, lastTimeFinishedChanged, count]); // CHECK ARRIVED_AT_STATION useEffect(() => { if ( !(corridorList && corridorList.length > 0 && position && stopStations) ) { return; } const currentEndStation = corridorList[corridorList.length - 1]; // Calculate distance between current train position and current end station const distTrainToCurrentEndStation = haversineDistance(position, [ currentEndStation.gpsCoordinates.lat, currentEndStation.gpsCoordinates.lng, ]); const ARRIVED_RADIUS = 0.5; if (distTrainToCurrentEndStation < ARRIVED_RADIUS) { const currentMovementOrder = stopStations[currentTripKey]?.order; const numberOfMovements = Object.keys(stopStations).length; const isLastMovement = currentMovementOrder === numberOfMovements - 1; if (isLastMovement) { dispatch(setFinished(true)); dispatch(setWaiting(false)); } else { dispatch(setWaiting(true)); } setCurrentRecommendation(null); setIncomingRecommendation(null); } }, [position, corridorList]); useEffect(() => { const startingAngle = getBearingAngle( [ corridorList[0]?.gpsCoordinates.lat, corridorList[0]?.gpsCoordinates.lng, ], [ corridorList[corridorList?.length - 1]?.gpsCoordinates.lat, corridorList[corridorList?.length - 1]?.gpsCoordinates.lng, ], ); setStartAngle(startingAngle); }, [corridorList]); // useEffect(() => { // if (trackingTrainId !== 'none' && trains.length > 0) { // const train = getCurrentTrain(trackingTrainId, trains); // if (train.position) { // const {latitude, longitude} = train.position; // setGpsDataToStore(); // regionRef.current = { // latitude, // longitude, // zoom: Math.floor(zoomScale), // zoomDetail: zoomScale, // }; // if (isReady) { // if (runningStatus || waitingStatus || !startPos?.length) { // setCameraMap(trains, latitude, longitude); // } else { // setCameraMap(trains, startPos[0], startPos[1], true); // } // } // } // } // }, [ // trains, // trackingTrainId, // mapRef, // zoomScale, // runningStatus, // waitingStatus, // startPos, // startAngle, // autoCenter, // loading, // ]); const startSetCameraCenter = async () => { const camera = await mapRef.current?.getCamera(); if (camera) { setCameraCenter(camera.center); } }; useEffect(() => { startSetCameraCenter(); }, []); const handleIncomingRecommendation = ( position: [number, number], milepost: number, speed: number, currentSegmentId: number, ) => { const recommendation = ModelInterface.getIncomingRecommendation( milepost, speed, corridorList, currentSegmentId, travelDistance, ); appendToModelFile( modelJsonFileName, ModelEventType.MODEL_RUN, location, recommendation, ); const filteredResult = filterInterface.filterRecommendation( recommendation, speed, ); if (filteredResult.filtered) { appendToModelFile( modelJsonFileName, ModelEventType.MODEL_FILTERED_RECOMMENDATION, location, recommendation, ); } if ( !incomingRecommendation && !currentRecommendation && recommendation && !filteredResult.filtered ) { setIncomingRecommendation({...recommendation, position: position}); appendToModelFile( modelJsonFileName, ModelEventType.MODEL_UI_INCOMING_RECOMMENDATIONS, location, recommendation, ); } }; const handleCurrentRecommendation = async ( position: [number, number], milepost: number, speed: number, ) => { const recommendation = ModelInterface.getCurrentRecommendation( milepost, speed, ); appendToModelFile( modelJsonFileName, ModelEventType.MODEL_RUN, location, recommendation, ); const isFiltered = filterInterface.filterRecommendation( recommendation, speed, ); if (isFiltered.filtered) { appendToModelFile( modelJsonFileName, ModelEventType.MODEL_FILTERED_RECOMMENDATION, location, recommendation, ); } if (!currentRecommendation && recommendation && !isFiltered.filtered) { setCurrentRecommendation({...recommendation, position: position}); appendToModelFile( modelJsonFileName, ModelEventType.MODEL_UI_ACTIVE_RECOMMENDATION_START, location, recommendation, ); } setIncomingRecommendation(null); }; // Check for incoming recommendation useEffect(() => { const currentSegmentId = getSegmentIdFromCoord( position, corridorListFilter, ); if (!currentTravelDistance.current) { currentTravelDistance.current = travelDistance; } if (Math.abs(travelDistance - currentTravelDistance.current) > 0.1) { currentTravelDistance.current = travelDistance; if (!incomingRecommendation && !currentRecommendation) { handleIncomingRecommendation( travelDistance, currentMilePost, currentSpeed, currentSegmentId, ); } else if ( incomingRecommendation && !currentRecommendation && travelDistance >= incomingRecommendation.targetDistance ) { handleCurrentRecommendation( travelDistance, currentMilePost, currentSpeed, ); } } }, [travelDistance, currentSpeed]); // Check to clear recommendation useEffect(() => { if (currentRecommendation) { if ( travelDistance - currentRecommendation.position > currentRecommendation.distance ) { appendToModelFile( modelJsonFileName, ModelEventType.MODEL_UI_ACTIVE_RECOMMENDATION_END, location, currentRecommendation, ); setCurrentRecommendation(null); } } }, [travelDistance, currentRecommendation]); useLogGPSLocation(gpsJsonFileName); return ( <> {loading && <Loader opacity={opacity} />} {/* Display or hide arrived/start buttons */} {finishedStatus ? ( <TouchableOpacity style={[ styles.btnStartStop, styles.wrapOver, { left: orientation === 'landscape' ? 260 : 145, }, ]} onPress={() => { const stationPair = currentTripKey.split('-'); dispatch( setEndStationHistory({ stationId: stationPair[1], arrivedTimeStamp: new Date().toString(), departedTimeStamp: null, }), ); dispatch(setFinished(false)); dispatch(setWaiting(false)); dispatch(setRunning(false)); dispatch(clearInstructionGroup()); navigation.navigate(ScreensName.TRIP_REVIEW); }}> <Text style={styles.btnArrivedAtStationText}>End Trip</Text> </TouchableOpacity> ) : waitingStatus && !confirmArrived ? ( <TouchableOpacity style={[ styles.btnStartStop, styles.wrapOver, { left: orientation === 'landscape' ? 260 : 145, }, ]} onPress={() => { if (waitingStatus) { const currentOrder = Object.values(stopStations).find( item => item.key === currentTripKey, )?.order; const nextRoute = Object.values(stopStations).find( item => item.order === currentOrder + 1, ); dispatch(setCurrentTripKey(nextRoute?.key || currentTripKey)); } dispatch(setRunning(false)); dispatch(cleanGpsList()); dispatch(clearModelEventList()); setTotalDistanceBase(travelDistance + totalDistanceBase); dispatch(setTravelDistance(0)); setConfirmArrived(true); setArriveTime(new Date().toString()); }}> <Text style={styles.btnArrivedAtStationText}>End Trip Section</Text> </TouchableOpacity> ) : waitingStatus ? ( <TouchableOpacity style={[ styles.btnStartStop, styles.wrapOver, { left: orientation === 'landscape' ? 260 : 145, }, ]} onPress={async () => { if (!gpsJsonFileName) { const fileName = generateGPSFileName( String(userAuthorization?.railroadId), String(simpleTrainConsist?.simpleTrainConsistId), ); setGPSJsonFileName(fileName); await createNewGPSFile( String(userAuthorization?.railroadId), String(simpleTrainConsist?.tripId), String(userAuthorization?.userId), fileName, location, String(simpleTrainConsist?.simpleTrainConsistId), String(consistTrain?.locomotiveModel), ); } const [currentStartStationId, currentEndStationId] = currentTripKey.split('-'); if (stationHistory?.startStationHistory) { dispatch( addStationHistoryItem({ stationId: currentStartStationId, arrivedTimeStamp: arriveTime, departedTimeStamp: new Date().toString(), }), ); } else { dispatch( setStartStationHistory({ stationId: currentStartStationId, arrivedTimeStamp: null, departedTimeStamp: new Date().toString(), }), ); } const loadModel = ModelInterface.selectModel( currentStartStationId, currentEndStationId, ); if (!modelJsonFileName) { const fileName = generateModelFileName( String(userAuthorization?.railroadId), String(simpleTrainConsist?.simpleTrainConsistId), ); setModelJsonFileName(fileName); await createNewModelFile( String(userAuthorization?.railroadId), String(simpleTrainConsist?.tripId), String(userAuthorization?.userId), fileName, location, String(simpleTrainConsist?.simpleTrainConsistId), String(consistTrain?.locomotiveModel), loadModel ? ModelEventType.MODEL_LOADED : ModelEventType.MODEL_LOAD_FAILED, ); } dispatch(setRunning(true)); setConfirmArrived(false); dispatch(setWaiting(false)); }}> <Text style={styles.btnStartText} testID="start-button"> Start Trip Section </Text> </TouchableOpacity> ) : runningStatus ? ( currentRecommendation ? ( <RecommendationItem instruction={currentRecommendation} travelValue={ currentRecommendation?.position + currentRecommendation?.distance - travelDistance } /> ) : null ) : ( <TouchableOpacity style={[ styles.btnStartStop, styles.wrapOver, { left: orientation === 'landscape' ? 260 : 145, }, ]} onPress={async () => { if (!gpsJsonFileName) { const fileName = generateGPSFileName( String(userAuthorization?.railroadId), String(simpleTrainConsist?.simpleTrainConsistId), ); setGPSJsonFileName(fileName); await createNewGPSFile( String(userAuthorization?.railroadId), String(simpleTrainConsist?.tripId), String(userAuthorization?.userId), fileName, location, String(simpleTrainConsist?.simpleTrainConsistId), String(consistTrain?.locomotiveModel), ); } const [currentStartStationId, currentEndStationId] = currentTripKey.split('-'); if (stationHistory?.startStationHistory) { dispatch( addStationHistoryItem({ stationId: currentStartStationId, arrivedTimeStamp: arriveTime, departedTimeStamp: new Date().toString(), }), ); } else { dispatch( setStartStationHistory({ stationId: currentStartStationId, arrivedTimeStamp: null, departedTimeStamp: new Date().toString(), }), ); } const loadModel = ModelInterface.selectModel( currentStartStationId, currentEndStationId, ); if (!modelJsonFileName) { const fileName = generateModelFileName( String(userAuthorization?.railroadId), String(simpleTrainConsist?.simpleTrainConsistId), ); setModelJsonFileName(fileName); await createNewModelFile( String(userAuthorization?.railroadId), String(simpleTrainConsist?.tripId), String(userAuthorization?.userId), fileName, location, String(simpleTrainConsist?.simpleTrainConsistId), String(consistTrain?.locomotiveModel), loadModel ? ModelEventType.MODEL_LOADED : ModelEventType.MODEL_LOAD_FAILED, ); } dispatch(setRunning(true)); }}> <Text style={styles.btnStartText} testID="start-button"> Start Trip </Text> </TouchableOpacity> )} <CloseTrip /> <ETA estimatedTime={estimatedTimeWithSpeedProfile} /> <View style={styles.wrapControlButtons}> <ZoomInOut mapRef={mapRef} zoomScale={zoomScale} setZoomScale={setZoomScale} /> <Recenter mapRef={mapRef} zoomScale={zoomScale} /> </View> <Speedometer /> <TrackGradeView track={corridorList} /> <RightWidget zoomScale={zoomScale} incomingRecommendation={incomingRecommendation} /> <ScaleBar zoomLevel={zoomScale || null} latitude={cameraCenter?.latitude || null} overridenStyles={{bottom: showTrackGradeView ? 270 : 70}} /> </> ); }; export default InfoCar;
Editor is loading...