Walking Tracker
Animated Walking Tracker with Stats Requires Trimble Maps v4.0.0 or later.<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="stylesheet" href="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.5.css" /> <script src="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.5.js"></script> <script src="https://cdn.jsdelivr.net/npm/@turf/turf@6/turf.min.js"></script> <style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; } #stats { position: absolute; top: 10px; left: 10px; background: rgba(0,0,0,0.6); color: #fff; padding: 10px 15px; border-radius: 8px; font-family: system-ui, sans-serif; } </style> </head> <body> <div id="map"></div> <div id="stats"> <div><b>Walking Tracker</b></div> <div id="distance">Distance: 0.00 km</div> <div id="time">Time: 0s</div> </div> <script> TrimbleMaps.setAPIKey('0D8BA43647605743A5FB4B225664EF0F'); const map = new TrimbleMaps.Map({ container: 'map', center: [-73.968285, 40.785091], // Central Park zoom: 13, pitch: 50, attributionControl: false, hash: true, }); // Walking route const routeCoords = [ [-73.9731, 40.7644], [-73.9712, 40.7681], [-73.9690, 40.7725], [-73.9660, 40.7770], [-73.9655, 40.7822], [-73.9685, 40.7851], [-73.9735, 40.7870], [-73.9770, 40.7840], [-73.9790, 40.7785], [-73.9780, 40.7715], [-73.9750, 40.7670], [-73.9731, 40.7644] // loop back ]; const route = turf.lineString(routeCoords); const routeLength = turf.length(route, {units: 'kilometers'}); let progress = 0; let distanceTravelled = 0; const speed = 0.0001; // fraction of route per frame const startTime = Date.now(); map.on('load', async () => { // Load custom walking icon const img = await map.loadImage('https://cdn-icons-png.flaticon.com/512/1077/1077012.png'); map.addImage('walker-icon', img.data, {sdf: false}); // Route line map.addSource('walk-route', { type: 'geojson', data: route }); map.addLayer({ id: 'walk-route-line', type: 'line', source: 'walk-route', paint: { 'line-color': '#ff7f0e', 'line-width': 4, 'line-dasharray': [2, 2] } }); // Walker icon map.addSource('walker', { type: 'geojson', data: turf.point(routeCoords[0]) }); map.addLayer({ id: 'walker', source: 'walker', type: 'symbol', layout: { 'icon-image': 'walker-icon', // ✅ custom loaded image 'icon-size': 0.08, // adjust size 'icon-rotate': ['get', 'bearing'], 'icon-rotation-alignment': 'map' } }); function animate() { progress += speed; if (progress > 1) progress = 0; // loop again const dist = progress * routeLength; const along = turf.along(route, dist, {units: 'kilometers'}); const next = turf.along(route, Math.min(dist + 0.001, routeLength), {units: 'kilometers'}); if (!along || !along.geometry) return; const bearing = turf.bearing(along, next); // Update walker position smoothly map.getSource('walker').setData({ type: 'Feature', geometry: along.geometry, properties: {bearing} }); // Update stats distanceTravelled = dist; const elapsedSec = Math.floor((Date.now() - startTime) / 1000); document.getElementById('distance').innerText = `Distance: ${distanceTravelled.toFixed(2)} km`; document.getElementById('time').innerText = `Time: ${elapsedSec}s`; requestAnimationFrame(animate); } animate(); }); </script> </body> </html>
Walking Tracker
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="stylesheet" href="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.5.css" /> <script src="https://maps-sdk.trimblemaps.com/v4/trimblemaps-4.2.5.js"></script> <script src="https://cdn.jsdelivr.net/npm/@turf/turf@6/turf.min.js"></script> <style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; } #stats { position: absolute; top: 10px; left: 10px; background: rgba(0,0,0,0.6); color: #fff; padding: 10px 15px; border-radius: 8px; font-family: system-ui, sans-serif; } </style> </head> <body> <div id="map"></div> <div id="stats"> <div><b>Walking Tracker</b></div> <div id="distance">Distance: 0.00 km</div> <div id="time">Time: 0s</div> </div> <script> TrimbleMaps.setAPIKey('0D8BA43647605743A5FB4B225664EF0F'); const map = new TrimbleMaps.Map({ container: 'map', center: [-73.968285, 40.785091], // Central Park zoom: 13, pitch: 50, attributionControl: false, hash: true, }); // Walking route const routeCoords = [ [-73.9731, 40.7644], [-73.9712, 40.7681], [-73.9690, 40.7725], [-73.9660, 40.7770], [-73.9655, 40.7822], [-73.9685, 40.7851], [-73.9735, 40.7870], [-73.9770, 40.7840], [-73.9790, 40.7785], [-73.9780, 40.7715], [-73.9750, 40.7670], [-73.9731, 40.7644] // loop back ]; const route = turf.lineString(routeCoords); const routeLength = turf.length(route, {units: 'kilometers'}); let progress = 0; let distanceTravelled = 0; const speed = 0.0001; // fraction of route per frame const startTime = Date.now(); map.on('load', async () => { // Load custom walking icon const img = await map.loadImage('https://cdn-icons-png.flaticon.com/512/1077/1077012.png'); map.addImage('walker-icon', img.data, {sdf: false}); // Route line map.addSource('walk-route', { type: 'geojson', data: route }); map.addLayer({ id: 'walk-route-line', type: 'line', source: 'walk-route', paint: { 'line-color': '#ff7f0e', 'line-width': 4, 'line-dasharray': [2, 2] } }); // Walker icon map.addSource('walker', { type: 'geojson', data: turf.point(routeCoords[0]) }); map.addLayer({ id: 'walker', source: 'walker', type: 'symbol', layout: { 'icon-image': 'walker-icon', // ✅ custom loaded image 'icon-size': 0.08, // adjust size 'icon-rotate': ['get', 'bearing'], 'icon-rotation-alignment': 'map' } }); function animate() { progress += speed; if (progress > 1) progress = 0; // loop again const dist = progress * routeLength; const along = turf.along(route, dist, {units: 'kilometers'}); const next = turf.along(route, Math.min(dist + 0.001, routeLength), {units: 'kilometers'}); if (!along || !along.geometry) return; const bearing = turf.bearing(along, next); // Update walker position smoothly map.getSource('walker').setData({ type: 'Feature', geometry: along.geometry, properties: {bearing} }); // Update stats distanceTravelled = dist; const elapsedSec = Math.floor((Date.now() - startTime) / 1000); document.getElementById('distance').innerText = `Distance: ${distanceTravelled.toFixed(2)} km`; document.getElementById('time').innerText = `Time: ${elapsedSec}s`; requestAnimationFrame(animate); } animate(); }); </script> </body> </html>