1 /* exported RouteOutput */
2 function RouteOutput(map) {
3 const popup = L.popup({ autoPanPadding: [100, 100] });
5 const polyline = L.polyline([], {
11 const highlight = L.polyline([], {
17 let distanceUnits = "km_m";
18 let downloadURL = null;
20 function translateDistanceUnits(m) {
21 if (distanceUnits === "mi_ft") {
22 return [m / 0.3048, "ft", m / 1609.344, "mi"];
23 } else if (distanceUnits === "mi_yd") {
24 return [m / 0.9144, "yd", m / 1609.344, "mi"];
26 return [m, "m", m / 1000, "km"];
30 function formatTotalDistance(minorValue, minorName, majorValue, majorName) {
31 const scope = "javascripts.directions.distance_in_units";
33 if (minorValue < 1000 || majorValue < 0.25) {
34 return OSM.i18n.t(minorName, { scope, distance: Math.round(minorValue) });
35 } else if (majorValue < 10) {
36 return OSM.i18n.t(majorName, { scope, distance: majorValue.toFixed(1) });
38 return OSM.i18n.t(majorName, { scope, distance: Math.round(majorValue) });
42 function formatStepDistance(minorValue, minorName, majorValue, majorName) {
43 const scope = "javascripts.directions.distance_in_units";
47 } else if (minorValue < 200) {
48 return OSM.i18n.t(minorName, { scope, distance: Math.round(minorValue / 10) * 10 });
49 } else if (minorValue < 1500 || majorValue < 0.25) {
50 return OSM.i18n.t(minorName, { scope, distance: Math.round(minorValue / 100) * 100 });
51 } else if (majorValue < 5) {
52 return OSM.i18n.t(majorName, { scope, distance: majorValue.toFixed(1) });
54 return OSM.i18n.t(majorName, { scope, distance: Math.round(majorValue) });
58 function formatHeight(minorValue, minorName) {
59 const scope = "javascripts.directions.distance_in_units";
61 return OSM.i18n.t(minorName, { scope, distance: Math.round(minorValue) });
64 function formatTime(s) {
65 let m = Math.round(s / 60);
66 const h = Math.floor(m / 60);
70 return h + ":" + (m < 10 ? "0" : "") + m;
73 function writeSummary(route) {
74 $("#directions_route_distance").val(formatTotalDistance(...translateDistanceUnits(route.distance)));
75 $("#directions_route_time").val(formatTime(route.time));
77 if (typeof route.ascend !== "undefined" && typeof route.descend !== "undefined") {
78 $("#directions_route_ascend_descend").prop("hidden", false);
79 $("#directions_route_ascend").val(formatHeight(...translateDistanceUnits(route.ascend)));
80 $("#directions_route_descend").val(formatHeight(...translateDistanceUnits(route.descend)));
82 $("#directions_route_ascend_descend").prop("hidden", true);
83 $("#directions_route_ascend").val("");
84 $("#directions_route_descend").val("");
88 function writeSteps(route) {
89 $("#directions_route_steps").empty();
91 for (const [i, [direction, instruction, dist, lineseg]] of route.steps.entries()) {
92 const row = $("<tr class='turn'/>").appendTo($("#directions_route_steps"));
95 row.append("<td class='ps-3'><svg width='20' height='20' class='d-block'><use href='#routing-sprite-" + direction + "' /></svg></td>");
97 row.append("<td class='ps-3'>");
100 row.append(`<td class="text-break"><b>${i + 1}.</b> ${instruction}`);
101 row.append("<td class='pe-3 distance text-body-secondary text-end'>" + formatStepDistance(...translateDistanceUnits(dist)));
103 row.on("click", function () {
105 .setLatLng(lineseg[0])
106 .setContent(`<p><b>${i + 1}.</b> ${instruction}</p>`)
111 .on("mouseenter", function () {
116 .on("mouseleave", function () {
117 map.removeLayer(highlight);
122 const routeOutput = {};
124 routeOutput.write = function (route) {
126 .setLatLngs(route.line)
132 $("#directions_distance_units_settings input").off().on("change", function () {
133 distanceUnits = this.value;
138 const blob = new Blob([JSON.stringify(polyline.toGeoJSON())], { type: "application/geo+json" });
140 URL.revokeObjectURL(downloadURL);
141 downloadURL = URL.createObjectURL(blob);
142 $("#directions_route_download").prop("href", downloadURL);
144 $("#directions_route_credit")
146 .prop("href", route.creditlink);
147 $("#directions_route_demo")
149 .prop("href", route.demolink);
152 routeOutput.fit = function () {
153 map.fitBounds(polyline.getBounds().pad(0.05));
156 routeOutput.isVisible = function () {
157 return map.hasLayer(polyline);
160 routeOutput.remove = function () {
163 .removeLayer(polyline);
165 $("#directions_distance_units_settings input").off();
167 $("#directions_route_steps").empty();
169 URL.revokeObjectURL(downloadURL);
170 $("#directions_route_download").prop("href", "");