Files
freemoto/app/web/static/route.js
2025-07-28 20:20:29 +02:00

171 lines
6.0 KiB
JavaScript

document.addEventListener('DOMContentLoaded', function() {
var avoidHighwaysCheckbox = document.getElementById('avoidHighways');
var useShortestCheckbox = document.getElementById('useShortest');
var avoidTollRoadsCheckbox = document.getElementById('avoidTollRoads');
var avoidFerriesCheckbox = document.getElementById('avoidFerries');
var avoidUnpavedCheckbox = document.getElementById('avoidUnpaved');
var points = [];
var markers = [];
var routePolyline = null;
function calculateRoute() {
if (points.length === 2) {
var options = {
"exclude_restrictions": true
};
if (avoidHighwaysCheckbox && avoidHighwaysCheckbox.checked) {
options.use_highways = 0;
}
if (useShortestCheckbox && useShortestCheckbox.checked) {
options.use_shortest = true;
}
if (avoidTollRoadsCheckbox && avoidTollRoadsCheckbox.checked) {
options.avoid_toll = true;
}
if (avoidFerriesCheckbox && avoidFerriesCheckbox.checked) {
options.avoid_ferry = true;
}
if (avoidUnpavedCheckbox && avoidUnpavedCheckbox.checked) {
options.avoid_unpaved = true;
}
var costing_options = { motorcycle: options };
var requestBody = {
locations: [
{ lat: points[0].lat, lon: points[0].lng },
{ lat: points[1].lat, lon: points[1].lng }
],
costing: "motorcycle",
costing_options: costing_options
};
fetch('/route', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(requestBody)
})
.then(response => response.json())
.then(data => {
var latlngs = decodePolyline6(data.trip.legs[0].shape);
if (routePolyline) {
map.removeLayer(routePolyline);
}
routePolyline = L.polyline(latlngs, { color: 'red', weight: 5}).addTo(map);
map.fitBounds(routePolyline.getBounds());
});
}
}
map.on('click', function(e) {
if (points.length < 2) {
var marker = L.marker(e.latlng).addTo(map);
markers.push(marker);
points.push(e.latlng);
marker.bindPopup(points.length === 1 ? "Start" : "End").openPopup();
}
calculateRoute();
});
// Listen for changes on all checkboxes
[
avoidHighwaysCheckbox,
useShortestCheckbox,
avoidTollRoadsCheckbox,
avoidFerriesCheckbox,
avoidUnpavedCheckbox
].forEach(function(checkbox) {
if (checkbox) {
checkbox.addEventListener('change', calculateRoute);
}
});
// Disable other checkboxes when "Use shortest route" is checked
useShortestCheckbox.addEventListener('change', function() {
var disable = useShortestCheckbox.checked;
[
avoidHighwaysCheckbox,
avoidTollRoadsCheckbox,
avoidFerriesCheckbox,
avoidUnpavedCheckbox
].forEach(function(cb) {
cb.disabled = disable;
});
});
// Adapted from Valhalla docs — polyline6 decoder for JS
function decodePolyline6(encoded) {
var coords = [];
var index = 0, lat = 0, lng = 0;
var shift = 0, result = 0, byte = null, latitude_change, longitude_change;
var factor = Math.pow(10, 6);
while (index < encoded.length) {
byte = shift = result = 0;
do {
byte = encoded.charCodeAt(index++) - 63;
result |= (byte & 0x1f) << shift;
shift += 5;
} while (byte >= 0x20);
latitude_change = (result & 1) ? ~(result >> 1) : (result >> 1);
shift = result = 0;
do {
byte = encoded.charCodeAt(index++) - 63;
result |= (byte & 0x1f) << shift;
shift += 5;
} while (byte >= 0x20);
longitude_change = (result & 1) ? ~(result >> 1) : (result >> 1);
lat += latitude_change;
lng += longitude_change;
coords.push([lat / factor, lng / factor]);
}
return coords;
}
// Remove Markers
function resetMarkers() {
markers.forEach(function(marker) {
map.removeLayer(marker);
});
markers = [];
points = [];
if (routePolyline) {
map.removeLayer(routePolyline);
routePolyline = null;
}
}
// Make resetMarkers available globally
window.resetMarkers = resetMarkers;
// Plot Route button logic
document.getElementById('plotRouteBtn').addEventListener('click', function() {
var sourceInput = document.getElementById('sourceInput');
var destInput = document.getElementById('destInput');
var sourceLat = parseFloat(sourceInput.dataset.lat);
var sourceLon = parseFloat(sourceInput.dataset.lon);
var destLat = parseFloat(destInput.dataset.lat);
var destLon = parseFloat(destInput.dataset.lon);
if (!isNaN(sourceLat) && !isNaN(sourceLon) && !isNaN(destLat) && !isNaN(destLon)) {
// Remove old markers
markers.forEach(function(marker) {
map.removeLayer(marker);
});
markers = [];
points = [];
// Add new markers
var startMarker = L.marker([sourceLat, sourceLon]).addTo(map).bindPopup("Start").openPopup();
var endMarker = L.marker([destLat, destLon]).addTo(map).bindPopup("End").openPopup();
markers.push(startMarker, endMarker);
points.push({lat: sourceLat, lng: sourceLon}, {lat: destLat, lng: destLon});
calculateRoute();
} else {
alert("Please enter valid addresses for both start and destination.");
}
});
});