1 OSM.DirectionsRouteOutput = function (map) {
2 const popup = L.popup({ autoPanPadding: [100, 100] });
4 const polyline = L.polyline([], {
10 const highlight = L.polyline([], {
16 let downloadURL = null;
18 function formatTotalDistance(m) {
19 const scope = "javascripts.directions.distance_in_units";
22 return OSM.i18n.t("m", { scope, distance: Math.round(m) });
23 } else if (m < 10000) {
24 return OSM.i18n.t("km", { scope, distance: (m / 1000.0).toFixed(1) });
26 return OSM.i18n.t("km", { scope, distance: Math.round(m / 1000) });
30 function formatStepDistance(m) {
31 const scope = "javascripts.directions.distance_in_units";
36 return OSM.i18n.t("m", { scope, distance: Math.round(m / 10) * 10 });
37 } else if (m < 1500) {
38 return OSM.i18n.t("m", { scope, distance: Math.round(m / 100) * 100 });
39 } else if (m < 5000) {
40 return OSM.i18n.t("km", { scope, distance: Math.round(m / 100) / 10 });
42 return OSM.i18n.t("km", { scope, distance: Math.round(m / 1000) });
46 function formatHeight(m) {
47 const scope = "javascripts.directions.distance_in_units";
49 return OSM.i18n.t("m", { scope, distance: Math.round(m) });
52 function formatTime(s) {
53 let m = Math.round(s / 60);
54 const h = Math.floor(m / 60);
56 return h + ":" + (m < 10 ? "0" : "") + m;
59 function writeSummary(route) {
60 $("#directions_route_distance").val(formatTotalDistance(route.distance));
61 $("#directions_route_time").val(formatTime(route.time));
62 if (typeof route.ascend !== "undefined" && typeof route.descend !== "undefined") {
63 $("#directions_route_ascend_descend").prop("hidden", false);
64 $("#directions_route_ascend").val(formatHeight(route.ascend));
65 $("#directions_route_descend").val(formatHeight(route.descend));
67 $("#directions_route_ascend_descend").prop("hidden", true);
68 $("#directions_route_ascend").val("");
69 $("#directions_route_descend").val("");
73 function writeSteps(route) {
74 $("#directions_route_steps").empty();
76 for (const [i, [direction, instruction, dist, lineseg]] of route.steps.entries()) {
77 const row = $("<tr class='turn'/>").appendTo($("#directions_route_steps"));
80 row.append("<td class='border-0'><svg width='20' height='20' class='d-block'><use href='#routing-sprite-" + direction + "' /></svg></td>");
82 row.append("<td class='border-0'>");
84 row.append(`<td><b>${i + 1}.</b> ${instruction}`);
85 row.append("<td class='distance text-body-secondary text-end'>" + formatStepDistance(dist));
87 row.on("click", function () {
89 .setLatLng(lineseg[0])
90 .setContent(`<p><b>${i + 1}.</b> ${instruction}</p>`)
95 .on("mouseenter", function () {
100 .on("mouseleave", function () {
101 map.removeLayer(highlight);
106 const routeOutput = {};
108 routeOutput.write = function (route) {
110 .setLatLngs(route.line)
116 const blob = new Blob([JSON.stringify(polyline.toGeoJSON())], { type: "application/json" });
117 URL.revokeObjectURL(downloadURL);
118 downloadURL = URL.createObjectURL(blob);
119 $("#directions_route_download").prop("href", downloadURL);
121 $("#directions_route_credit")
123 .prop("href", route.creditlink);
126 routeOutput.fit = function () {
127 map.fitBounds(polyline.getBounds().pad(0.05));
130 routeOutput.isVisible = function () {
131 return map.hasLayer(polyline);
134 routeOutput.remove = function () {
137 .removeLayer(polyline);
139 $("#directions_route_steps").empty();
141 URL.revokeObjectURL(downloadURL);
142 $("#directions_route_download").prop("href", "");