```javascript // Initialize map const map = L.map('map').setView([37.5665, 126.9780], 13); // Default to Seoul L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); // Tracking variables let tracking = false; let startTime = null; let path = []; let polyline = null; let totalDistance = 0; let watchId = null; // DOM elements const startBtn = document.getElementById('startBtn'); const stopBtn = document.getElementById('stopBtn'); const saveBtn = document.getElementById('saveBtn'); const distanceEl = document.getElementById('distance'); const durationEl = document.getElementById('duration'); const speedEl = document.getElementById('speed'); const caloriesEl = document.getElementById('calories'); const historyTable = document.getElementById('historyTable'); // Event listeners startBtn.addEventListener('click', startTracking); stopBtn.addEventListener('click', stopTracking); saveBtn.addEventListener('click', saveSession); function startTracking() { tracking = true; startTime = new Date(); path = []; totalDistance = 0; if (polyline) { map.removeLayer(polyline); } startBtn.disabled = true; stopBtn.disabled = false; saveBtn.disabled = true; watchId = navigator.geolocation.watchPosition( updatePosition, handleError, { enableHighAccuracy: true, maximumAge: 10000, timeout: 5000 } ); updateTimer(); timerInterval = setInterval(updateTimer, 1000); } function stopTracking() { tracking = false; if (watchId) { navigator.geolocation.clearWatch(watchId); } startBtn.disabled = false; stopBtn.disabled = true; saveBtn.disabled = false; clearInterval(timerInterval); } function saveSession() { // Save to local storage const sessions = JSON.parse(localStorage.getItem('trackingSessions') || '[]'); const duration = (new Date() - startTime) / 1000; sessions.push({ date: new Date().toLocaleString(), distance: totalDistance, duration: formatTime(duration), path: path }); localStorage.setItem('trackingSessions', JSON.stringify(sessions)); updateHistoryTable(); saveBtn.disabled = true; } function updatePosition(position) { const { latitude, longitude, speed, altitude } = position.coords; const newPoint = [latitude, longitude]; // Add to path path.push(newPoint); // Update polyline if (polyline) { map.removeLayer(polyline); } polyline = L.polyline(path, {color: 'blue'}).addTo(map); // Calculate distance if (path.length > 1) { const lastPoint = path[path.length - 2]; const distance = calculateDistance(lastPoint[0], lastPoint[1], latitude, longitude); totalDistance += distance; distanceEl.textContent = (totalDistance / 1000).toFixed(2); } // Update speed const speedKmh = speed ? (speed * 3.6).toFixed(1) : 0; speedEl.textContent = speedKmh; // Estimate calories (very rough estimate) const calories = (totalDistance / 1000) * 60; // 60kcal per km caloriesEl.textContent = Math.round(calories); // Center map on current position map.setView(newPoint, map.getZoom()); } function handleError(error) { console.error('Geolocation error:', error.message); if (tracking) { stopTracking(); alert('Geolocation error: ' + error.message); } } function updateTimer() { if (!startTime) return; const elapsed = (new Date() - startTime) / 1000; durationEl.textContent = formatTime(elapsed); } function formatTime(seconds) { const hrs = Math.floor(seconds / 3600); const mins = Math.floor((seconds % 3600) / 60); const secs = Math.floor(seconds % 60); return `${hrs.toString().padStart(2, '0')}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; } function calculateDistance(lat1, lon1, lat2, lon2) { const R = 6371e3; // Earth radius in meters const φ1 = lat1 * Math.PI/180; 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; } function updateHistoryTable() { const sessions = JSON.parse(localStorage.getItem('trackingSessions') || '[]'); historyTable.innerHTML = sessions.map(session => `