171 lines
6.0 KiB
JavaScript
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.");
|
|
}
|
|
});
|
|
}); |