Rewrote UI, added option to export as gpx

This commit is contained in:
Pedan
2025-07-29 17:16:14 +02:00
parent 05a8d7abbd
commit 24e735e113
3 changed files with 214 additions and 65 deletions

View File

@@ -47,7 +47,22 @@ document.addEventListener('DOMContentLoaded', function() {
})
.then(response => response.json())
.then(data => {
var latlngs = decodePolyline6(data.trip.legs[0].shape);
var leg = data.trip && data.trip.legs && data.trip.legs[0];
var infoCard = document.getElementById('routeInfoCard');
if (leg && leg.summary && typeof leg.summary.length === 'number' && typeof leg.summary.time === 'number') {
var distanceKm = (leg.summary.length / 1000).toFixed(1); // meters to km
var durationMin = Math.round(leg.summary.time / 60); // seconds to minutes
var info = `<strong>Distance:</strong> ${distanceKm} km<br>
<strong>Estimated Time:</strong> ${durationMin} min<br>
<strong>Motorcycle Profile</strong>`;
infoCard.innerHTML = info;
infoCard.classList.remove('d-none');
} else {
infoCard.innerHTML = `<strong>Route info unavailable.</strong>`;
infoCard.classList.remove('d-none');
console.log('Valhalla response:', data);
}
var latlngs = decodePolyline6(leg.shape);
if (routePolyline) {
map.removeLayer(routePolyline);
}
@@ -63,6 +78,13 @@ document.addEventListener('DOMContentLoaded', function() {
markers.push(marker);
points.push(e.latlng);
marker.bindPopup(points.length === 1 ? "Start" : "End").openPopup();
// Reverse geocode and fill address field
if (points.length === 1) {
reverseGeocode(e.latlng.lat, e.latlng.lng, 'sourceInput');
} else if (points.length === 2) {
reverseGeocode(e.latlng.lat, e.latlng.lng, 'destInput');
}
}
calculateRoute();
});
@@ -135,6 +157,15 @@ document.addEventListener('DOMContentLoaded', function() {
map.removeLayer(routePolyline);
routePolyline = null;
}
// Clear address fields
var sourceInput = document.getElementById('sourceInput');
var destInput = document.getElementById('destInput');
sourceInput.value = '';
destInput.value = '';
delete sourceInput.dataset.lat;
delete sourceInput.dataset.lon;
delete destInput.dataset.lat;
delete destInput.dataset.lon;
}
// Make resetMarkers available globally
@@ -168,4 +199,56 @@ document.addEventListener('DOMContentLoaded', function() {
alert("Please enter valid addresses for both start and destination.");
}
});
function reverseGeocode(lat, lon, inputId) {
fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}`)
.then(response => response.json())
.then(data => {
var input = document.getElementById(inputId);
if (data && data.address) {
// Use the same format as your autocomplete
input.value = formatAddress(data);
} else {
input.value = `${lat}, ${lon}`;
}
input.dataset.lat = lat;
input.dataset.lon = lon;
});
}
function exportRouteAsGPX(latlngs) {
if (!latlngs || latlngs.length === 0) {
alert("No route to export.");
return;
}
let gpx =
`<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="FreeMoto" xmlns="http://www.topografix.com/GPX/1/1">
<trk>
<name>FreeMoto Route</name>
<trkseg>
${latlngs.map(pt => ` <trkpt lat="${pt[0]}" lon="${pt[1]}"></trkpt>`).join('\n')}
</trkseg>
</trk>
</gpx>`;
let blob = new Blob([gpx], {type: "application/gpx+xml"});
let url = URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = "freemoto-route.gpx";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
document.getElementById('exportGpxBtn').addEventListener('click', function() {
if (routePolyline) {
// routePolyline.getLatLngs() returns array of LatLng objects
let latlngs = routePolyline.getLatLngs().map(ll => [ll.lat, ll.lng]);
exportRouteAsGPX(latlngs);
} else {
alert("No route to export.");
}
});
});