deepsite-project / tracking.js
yunyongsu's picture
트래킹 어플 만들어 줘
bf00dfa verified
```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: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> 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 => `
<tr>
<td>${session.date}</td>
<td>${(session.distance / 1000).toFixed(2)} km</td>
<td>${session.duration}</td>
<td><button class="btn btn-sm btn-outline-primary">View</button></td>
</tr>
`).join('');
}
// Initialize
updateHistoryTable();
```