diff --git a/app/assets/javascripts/index/directions.js b/app/assets/javascripts/index/directions.js index 356dc6271d..0ac66d9d64 100644 --- a/app/assets/javascripts/index/directions.js +++ b/app/assets/javascripts/index/directions.js @@ -3,7 +3,7 @@ //= require_tree ./directions OSM.Directions = function (map) { - var routeRequest = null; // jqXHR object of an ongoing route request or null + let controller = null; // the AbortController for the current route request if a route request is in progress var chosenEngine; var popup = L.popup({ autoPanPadding: [100, 100] }); @@ -23,7 +23,7 @@ OSM.Directions = function (map) { var endpointDragCallback = function (dragging) { if (!map.hasLayer(polyline)) return; if (dragging && !chosenEngine.draggable) return; - if (dragging && routeRequest) return; + if (dragging && controller) return; getRoute(false, !dragging); }; @@ -109,7 +109,7 @@ OSM.Directions = function (map) { function getRoute(fitRoute, reportErrors) { // Cancel any route that is already in progress - if (routeRequest) routeRequest.abort(); + if (controller) controller.abort(); const points = endpoints.map(p => p.latlng); @@ -126,20 +126,8 @@ OSM.Directions = function (map) { // again. $("#sidebar_content").html($(".directions_form .loader_copy").html()); map.setSidebarOverlaid(false); - - routeRequest = chosenEngine.getRoute(points, function (err, route) { - routeRequest = null; - - if (err) { - map.removeLayer(polyline); - - if (reportErrors) { - $("#sidebar_content").html("
" + I18n.t("javascripts.directions.errors.no_route") + "
"); - } - - return; - } - + controller = new AbortController(); + chosenEngine.getRoute(points, controller.signal).then(function (route) { polyline .setLatLngs(route.line) .addTo(map); @@ -212,6 +200,13 @@ OSM.Directions = function (map) { map.setSidebarOverlaid(true); // TODO: collapse width of sidebar back to previous }); + }).catch(function () { + map.removeLayer(polyline); + if (reportErrors) { + $("#sidebar_content").html("
" + I18n.t("javascripts.directions.errors.no_route") + "
"); + } + }).finally(function () { + controller = null; }); function getDistText(dist) { diff --git a/app/assets/javascripts/index/directions/fossgis_osrm.js b/app/assets/javascripts/index/directions/fossgis_osrm.js index bb968f2da3..0dd91e57ed 100644 --- a/app/assets/javascripts/index/directions/fossgis_osrm.js +++ b/app/assets/javascripts/index/directions/fossgis_osrm.js @@ -154,15 +154,15 @@ creditline: "OSRM (FOSSGIS)", draggable: true, - getRoute: function (points, callback) { - const data = [ - { name: "overview", value: "false" }, - { name: "geometries", value: "polyline" }, - { name: "steps", value: true } - ]; + getRoute: function (points, signal) { + const query = new URLSearchParams({ + overview: "false", + geometries: "polyline", + steps: true + }); if (cachedHints.length === points.length) { - data.push({ name: "hints", value: cachedHints.join(";") }); + query.set("hints", cachedHints.join(";")); } else { // invalidate cache cachedHints = []; @@ -170,22 +170,15 @@ const req_path = "routed-" + vehicleType + "/route/v1/driving/" + points.map(p => p.lng + "," + p.lat).join(";"); - return $.ajax({ - url: OSM.FOSSGIS_OSRM_URL + req_path, - data, - dataType: "json", - success: function (response) { + return fetch(OSM.FOSSGIS_OSRM_URL + req_path + "?" + query, { signal }) + .then(response => response.json()) + .then(response => { if (response.code !== "Ok") { - return callback(true); + throw new TypeError("Response " + response.code); } - cachedHints = response.waypoints.map(wp => wp.hint); - callback(false, _processDirections(response.routes[0])); - }, - error: function () { - callback(true); - } - }); + return _processDirections(response.routes[0]); + }); } }; } diff --git a/app/assets/javascripts/index/directions/fossgis_valhalla.js b/app/assets/javascripts/index/directions/fossgis_valhalla.js index bbccccb13d..49f123bb8b 100644 --- a/app/assets/javascripts/index/directions/fossgis_valhalla.js +++ b/app/assets/javascripts/index/directions/fossgis_valhalla.js @@ -87,8 +87,8 @@ "Valhalla (FOSSGIS)", draggable: false, - getRoute: function (points, callback) { - const data = { + getRoute: function (points, signal) { + const query = new URLSearchParams({ json: JSON.stringify({ locations: points.map(function (p) { return { lat: p.lat, lon: p.lng, radius: 5 }; @@ -99,22 +99,15 @@ language: I18n.currentLocale() } }) - }; - return $.ajax({ - url: OSM.FOSSGIS_VALHALLA_URL, - data, - dataType: "json", - success: function ({ trip }) { - if (trip.status === 0) { - callback(false, _processDirections(trip.legs)); - } else { - callback(true); - } - }, - error: function () { - callback(true); - } }); + return fetch(OSM.FOSSGIS_VALHALLA_URL + "?" + query, { signal }) + .then(response => response.json()) + .then(({ trip }) => { + if (trip.status !== 0) { + throw new TypeError("Response status " + trip.status); + } + return _processDirections(trip.legs); + }); } }; } diff --git a/app/assets/javascripts/index/directions/graphhopper.js b/app/assets/javascripts/index/directions/graphhopper.js index 1914758730..8c1b7eb850 100644 --- a/app/assets/javascripts/index/directions/graphhopper.js +++ b/app/assets/javascripts/index/directions/graphhopper.js @@ -51,33 +51,26 @@ creditline: "GraphHopper", draggable: false, - getRoute: function (points, callback) { + getRoute: function (points, signal) { // GraphHopper Directions API documentation // https://graphhopper.com/api/1/docs/routing/ - const data = { + const query = new URLSearchParams({ vehicle: vehicleType, locale: I18n.currentLocale(), key: "LijBPDQGfu7Iiq80w3HzwB4RUDJbMbhs6BU0dEnn", elevation: false, instructions: true, - turn_costs: vehicleType === "car", - point: points.map(p => p.lat + "," + p.lng) - }; - return $.ajax({ - url: OSM.GRAPHHOPPER_URL, - data, - traditional: true, - dataType: "json", - success: function ({ paths }) { + turn_costs: vehicleType === "car" + }); + points.forEach(p => query.append("point", p.lat + "," + p.lng)); + return fetch(OSM.GRAPHHOPPER_URL + "?" + query, { signal }) + .then(response => response.json()) + .then(({ paths }) => { if (!paths || paths.length === 0) { - return callback(true); + throw new TypeError("Response empty"); } - callback(false, _processDirections(paths[0])); - }, - error: function () { - callback(true); - } - }); + return _processDirections(paths[0]); + }); } }; }