Untitled
unknown
plain_text
10 months ago
11 kB
4
Indexable
import React, { useState, useEffect } from 'react'; function GeolocationTracker() { const [isCollecting, setIsCollecting] = useState(true); const [startTime, setStartTime] = useState(null); const [lastTime, setLastTime] = useState(null); const [distance, setDistance] = useState(0); const [startPosition, setStartPosition] = useState(null); const [lastPosition, setLastPosition] = useState(null); const [speed, setSpeed] = useState(0); const [accelerationY, setAccelerationY] = useState(0); const [accuracy, setAccuracy] = useState(null); const [isDriving, setIsDriving] = useState(false); const [currentTime, setCurrentTime] = useState(0); const [speedProfile, setSpeedProfile] = useState([]); useEffect(() => { if (!isCollecting) return; const watchId = navigator.geolocation.watchPosition( function(position) { const currentTime = new Date().getTime(); if (!startTime) { setStartTime(currentTime); setLastTime(currentTime); setStartPosition({ latitude: position.coords.latitude, longitude: position.coords.longitude }); setLastPosition({ latitude: position.coords.latitude, longitude: position.coords.longitude }); } else { const deltaTime = (currentTime - lastTime) / 1000; // in seconds const currentDistance = calculateDistance(lastPosition.latitude, lastPosition.longitude, position.coords.latitude, position.coords.longitude); setDistance(distance + currentDistance); const currentSpeed = currentDistance / deltaTime; setSpeed(currentSpeed); setLastTime(currentTime); setLastPosition({ latitude: position.coords.latitude, longitude: position.coords.longitude }); // Add data to speed profile setSpeedProfile(prevProfile => [...prevProfile, { time: currentTime, speed: currentSpeed, distance: distance }]); } setAccuracy(position.coords.accuracy); setIsDriving(position.coords.speed > 0.1); // Assuming speed > 0.1 m/s indicates driving }, function(error) { console.error('Error getting geolocation:', error); }, { maximumAge: 0, enableHighAccuracy: true } ); const handleMotionEvent = (event) => { setAccelerationY(event.accelerationIncludingGravity.y); }; window.addEventListener('devicemotion', handleMotionEvent); const intervalId = setInterval(() => { setCurrentTime((new Date().getTime() - startTime) / 1000); }, 1000); return () => { clearInterval(intervalId); navigator.geolocation.clearWatch(watchId); window.removeEventListener('devicemotion', handleMotionEvent); }; }, [isCollecting, startTime, lastTime, distance, lastPosition]); const calculateDistance = (lat1, lon1, lat2, lon2) => { const R = 6371e3; // metres const φ1 = (lat1 * Math.PI) / 180; // φ, λ in radians const φ2 = (lat2 * Math.PI) / 180; const Δφ = ((lat2 - lat1) * Math.PI) / 180; const Δλ = ((lon2 - lon1) * Math.PI) / 180; const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; // in meters }; const clearData = () => { setIsCollecting(false); setStartTime(null); setLastTime(null); setDistance(0); setStartPosition(null); setLastPosition(null); setSpeed(0); setAccelerationY(0); setAccuracy(null); setIsDriving(false); setCurrentTime(0); setSpeedProfile([]); }; const restartCollecting = () => { setIsCollecting(true); setStartTime(null); setLastTime(null); setDistance(0); setStartPosition(null); setLastPosition(null); setSpeed(0); setAccelerationY(0); setAccuracy(null); setIsDriving(false); setCurrentTime(0); setSpeedProfile([]); }; return ( <div style={styles.overlay}> <div className="container" style={styles.container}> <h2 style={{color:'white'}}>Speed Coach</h2> <table style={styles.table}> <tbody> <tr style={styles.row}> <td style={styles.label}>State:</td> <td style={styles.data}>{isDriving ? 'Driving' : 'Standing'}</td> </tr> <tr style={styles.row}> <td style={styles.label}>GPS Speed:</td> <td style={styles.data}>{speed.toFixed(2)} m/s</td> </tr> <tr style={styles.row}> <td style={styles.label}>Y Acceleration:</td> <td style={styles.data}>{accelerationY.toFixed(2)}</td> </tr> {/*<tr style={styles.row}>*/} {/* <td style={styles.label}>GPS Position:</td>*/} {/* <td style={styles.data}>*/} {/* {`lat: ${lastPosition?.latitude?.toFixed(6) || 'N/A'}, lng: ${lastPosition?.longitude?.toFixed(6) || 'N/A'}`}*/} {/* </td>*/} {/*</tr>*/} <tr style={styles.row}> <td style={styles.label}>GPS Accuracy:</td> <td style={styles.data}>{accuracy ? `${accuracy} meters` : 'N/A'}</td> </tr> <tr style={styles.row}> <td style={styles.label}>Distance from start:</td> <td style={styles.data}>{distance.toFixed(2)} meters</td> </tr> </tbody> </table> {/*<div style={styles.listViewContainer}>*/} {/* <div style={styles.listView}>*/} {/* <div style={styles.listViewItem}>*/} {/* <p>Speed Profile Seconds</p>*/} {/* {speedProfile.map((entry, index) => (*/} {/* <p key={index}>{entry.time.toFixed(2)}</p>*/} {/* ))}*/} {/* </div>*/} {/* <div style={styles.listViewItem}>*/} {/* <p>km/h</p>*/} {/* {speedProfile.map((entry, index) => (*/} {/* <p key={index}>{((entry.speed * 3600) /*/} {/* 1000).toFixed(2)}</p>*/} {/* ))}*/} {/* </div>*/} {/* <div style={styles.listViewItem}>*/} {/* <p>m</p>*/} {/* {speedProfile.map((entry, index) => (*/} {/* <p key={index}>{entry.distance.toFixed(2)}</p>*/} {/* ))}*/} {/* </div>*/} {/* </div>*/} {/*</div>*/} <div style={styles.listViewContainer}> <div style={styles.listViewHeader}> <p>Speed Profile Seconds</p> <p>km/h</p> <p>m</p> </div> <div style={styles.listView}> <div style={styles.listViewItem}> {speedProfile.map((entry, index) => ( <p key={index}>{entry.time.toFixed(2)}</p> ))} </div> <div style={styles.listViewItem}> {speedProfile.map((entry, index) => ( <p key={index}>{((entry.speed * 3600) / 1000).toFixed(2)}</p> ))} </div> <div style={styles.listViewItem}> {speedProfile.map((entry, index) => ( <p key={index}>{entry.distance.toFixed(2)}</p> ))} </div> </div> </div> </div> <button style={styles.button} onClick={isCollecting ? clearData : restartCollecting} > {isCollecting ? 'Clear' : 'Restart'} </button> </div> ); } const styles = { overlay: { position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'black', display: 'flex', justifyContent: 'center', alignItems: 'center', flexDirection: 'column', color: 'white', }, container: { backgroundColor: 'rgba(38,38,38,255)', padding: '20px', borderRadius: '8px', width: '90%', maxWidth: '400px', textAlign: 'center', marginBottom: '20px', }, table: { width: '100%', borderCollapse: 'collapse', marginBottom: '20px', color: 'white', }, row: { borderBottom: '1px solid rgba(0, 0, 0, 0.1)', }, label: { textAlign: 'left', padding: '10px', fontWeight: 'bold', }, data: { textAlign: 'right', padding: '10px', }, button: { marginTop: '20px', padding: '10px 20px', backgroundColor: 'purple', color: '#fff', border: 'none', borderRadius: '5px', cursor: 'pointer', fontWeight: 'bold', }, listViewContainer: { width: '90%', maxWidth: '400px', backgroundColor: 'rgba(38,38,38,255)', padding: '20px', borderRadius: '8px', textAlign: 'center', color: 'white', height: '150px', overflowY: 'auto', // Add this line position: 'relative', // Add this line }, listViewHeader: { display: 'flex', top: '0', // Add this line backgroundColor: 'rgba(38,38,38,255)', // Add this line padding: '10px 0', // Add this line justifyContent: 'space-between', overflow:'false' }, listView: { display: 'flex', justifyContent: 'space-between', }, listViewItem: { flex: 1, justifyContent: 'space-between', }, }; export default GeolocationTracker;
Editor is loading...
Leave a Comment