mowing execution
This commit is contained in:
@@ -9,6 +9,10 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
|
|||||||
const [tracking, setTracking] = useState(false);
|
const [tracking, setTracking] = useState(false);
|
||||||
const [isPaused, setIsPaused] = useState(false);
|
const [isPaused, setIsPaused] = useState(false);
|
||||||
const [gpsTrack, setGpsTrack] = useState([]);
|
const [gpsTrack, setGpsTrack] = useState([]);
|
||||||
|
const [currentLocation, setCurrentLocation] = useState(null);
|
||||||
|
const [currentSpeed, setCurrentSpeed] = useState(0);
|
||||||
|
const [previousLocation, setPreviousLocation] = useState(null);
|
||||||
|
const [previousTime, setPreviousTime] = useState(null);
|
||||||
const [startTime, setStartTime] = useState(null);
|
const [startTime, setStartTime] = useState(null);
|
||||||
const [totalDistance, setTotalDistance] = useState(0);
|
const [totalDistance, setTotalDistance] = useState(0);
|
||||||
const totalDistanceRef = useRef(0);
|
const totalDistanceRef = useRef(0);
|
||||||
@@ -41,17 +45,26 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
|
|||||||
requestWakeLock();
|
requestWakeLock();
|
||||||
setTracking(true); setIsPaused(false);
|
setTracking(true); setIsPaused(false);
|
||||||
if (!startTime) setStartTime(new Date());
|
if (!startTime) setStartTime(new Date());
|
||||||
|
setPreviousLocation(null); setPreviousTime(null);
|
||||||
const id = navigator.geolocation.watchPosition((pos) => {
|
const id = navigator.geolocation.watchPosition((pos) => {
|
||||||
const { latitude, longitude, speed } = pos.coords;
|
const { latitude, longitude, accuracy, speed } = pos.coords;
|
||||||
const pt = { lat: latitude, lng: longitude, timestamp: new Date(pos.timestamp).toISOString(), speed: speed || 0 };
|
const timestamp = new Date(pos.timestamp);
|
||||||
setGpsTrack(prev => {
|
const pt = { lat: latitude, lng: longitude, accuracy, timestamp: timestamp.toISOString(), speed: speed || 0 };
|
||||||
if (prev.length > 0) {
|
setCurrentLocation({ lat: latitude, lng: longitude, accuracy });
|
||||||
const meters = haversineMeters(prev[prev.length-1], pt);
|
// Calculate speed/distance similar to Applications execution
|
||||||
|
if (previousLocation && previousTime) {
|
||||||
|
const meters = haversineMeters(previousLocation, pt);
|
||||||
|
const dt = (timestamp - previousTime) / 1000; // seconds
|
||||||
|
if (dt > 0) {
|
||||||
|
const mph = (meters / dt) * 2.237;
|
||||||
|
setCurrentSpeed(mph);
|
||||||
const newTotal = totalDistanceRef.current + meters; totalDistanceRef.current = newTotal; setTotalDistance(newTotal);
|
const newTotal = totalDistanceRef.current + meters; totalDistanceRef.current = newTotal; setTotalDistance(newTotal);
|
||||||
const seconds = startTime ? ((new Date(pos.timestamp)-startTime)/1000) : 0; if (seconds>0) setAverageSpeed((newTotal/seconds)*2.237);
|
const elapsed = startTime ? ((timestamp - startTime) / 1000) : 0; if (elapsed > 0) setAverageSpeed((newTotal / elapsed) * 2.237);
|
||||||
}
|
}
|
||||||
return [...prev, pt];
|
}
|
||||||
});
|
setPreviousLocation({ lat: latitude, lng: longitude });
|
||||||
|
setPreviousTime(timestamp);
|
||||||
|
setGpsTrack(prev => [...prev, pt]);
|
||||||
}, (err)=> toast.error('GPS error: '+err.message), { enableHighAccuracy: true, timeout: 5000, maximumAge: 1000 });
|
}, (err)=> toast.error('GPS error: '+err.message), { enableHighAccuracy: true, timeout: 5000, maximumAge: 1000 });
|
||||||
setWatchId(id);
|
setWatchId(id);
|
||||||
};
|
};
|
||||||
@@ -114,7 +127,17 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
|
|||||||
<div><span className="font-medium">Cut Height:</span> {plan.cut_height_inches}"</div>
|
<div><span className="font-medium">Cut Height:</span> {plan.cut_height_inches}"</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-80 border rounded mb-4">
|
<div className="h-80 border rounded mb-4">
|
||||||
<PropertyMap property={null} sections={sections} selectedSections={sections.map(s=>s.id)} mode="execution" gpsTrack={gpsTrack} currentLocation={null} center={center} zoom={center?16:15} />
|
<PropertyMap
|
||||||
|
property={null}
|
||||||
|
sections={sections}
|
||||||
|
selectedSections={sections.map(s=>s.id)}
|
||||||
|
mode="execution"
|
||||||
|
gpsTrack={gpsTrack}
|
||||||
|
currentLocation={currentLocation}
|
||||||
|
center={center || [39.8283, -98.5795]}
|
||||||
|
zoom={center ? 16 : 15}
|
||||||
|
className="h-80 w-full"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-3 mb-4">
|
<div className="flex gap-3 mb-4">
|
||||||
{!tracking ? (
|
{!tracking ? (
|
||||||
@@ -130,6 +153,7 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
|
|||||||
<div><span className="font-medium">Points:</span> {gpsTrack.length}</div>
|
<div><span className="font-medium">Points:</span> {gpsTrack.length}</div>
|
||||||
<div><span className="font-medium">Distance:</span> {(totalDistance*3.28084).toFixed(0)} ft</div>
|
<div><span className="font-medium">Distance:</span> {(totalDistance*3.28084).toFixed(0)} ft</div>
|
||||||
<div><span className="font-medium">Avg Speed:</span> {averageSpeed.toFixed(1)} mph</div>
|
<div><span className="font-medium">Avg Speed:</span> {averageSpeed.toFixed(1)} mph</div>
|
||||||
|
<div className="col-span-4 text-xs text-gray-500">Current: {currentSpeed.toFixed(1)} mph {currentLocation?.accuracy ? `(±${Math.round(currentLocation.accuracy)}m)` : ''}</div>
|
||||||
<div><span className="font-medium">Duration:</span> {startTime ? Math.round((new Date()-startTime)/60000) : 0} min</div>
|
<div><span className="font-medium">Duration:</span> {startTime ? Math.round((new Date()-startTime)/60000) : 0} min</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -138,4 +162,3 @@ const MowingExecutionModal = ({ plan, onClose, onComplete }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default MowingExecutionModal;
|
export default MowingExecutionModal;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user