brouter-web: hover box above the route; color route by slope (BalDav palette)

- .height-focus.label (on-map hover box) lifted 42px so it no longer covers
  the route line.
- Repoint the 'Route quality' overlay's incline provider from signed incline
  (degrees, blue->green->red) to |grade %| with BalDav's discrete bands
  (green->yellow->red->brown->black, >=10% black), via addInitHook before the
  control is built; best-effort auto-enable the overlay.
This commit is contained in:
4aiman 2026-09-09 21:31:40 +03:00
commit 78cb6594df

View file

@ -40,6 +40,8 @@
// guide lines/markers were near-black (#141414) — invisible on the dark chart
"body.bw-dark .focusLine line,body.bw-dark .height-focus.line{stroke:#aab4be!important}",
"body.bw-dark .height-focus.circle{stroke:#20242a!important}",
// lift the on-map hover box above the route so it doesn't cover the line (both themes)
".height-focus.label{transform:translateY(-42px)}",
// right vertical sidebar tab strip (layers/settings/data/stats icons)
"body.bw-dark .leaflet-sidebar-tabs,body.bw-dark .leaflet-sidebar-tabs>ul,body.bw-dark .leaflet-sidebar-tabs li,body.bw-dark .leaflet-sidebar-tabs li a{background:#20242a!important;color:#dfe3e8!important}",
"body.bw-dark .leaflet-sidebar-tabs li.active a,body.bw-dark .leaflet-sidebar-tabs li a:hover{background:#2b3038!important;color:#fff!important}",
@ -98,15 +100,83 @@
try { localStorage.setItem("baldav_bw_overlays_v1", "1"); } catch (e) {}
return true;
}
// --- Route colored by slope, BalDav palette (task: paint the route by gradient, not
// elevation). brouter-web's "Route quality" overlay uses a HotLineQualityProvider; its
// `incline` provider colors by SIGNED incline in degrees (blue→green→red). We repoint it
// at |grade %| with BalDav's discrete bands (green→yellow→red→brown→black, ≥10% black).
// The provider reads hotlineOptions.{min,max,palette} and valueFunction directly at draw
// time (computeLayers → L.hotline), so mutating them is enough. Registered via addInitHook
// BEFORE the control is constructed, so the very first draw already uses our palette.
var BANDS = ["#2e7d32","#7cb342","#aeea00","#ffeb3b","#ffc107","#ff9800","#ff5722","#e53935","#b71c1c","#6d4c41","#000000"];
function slopePalette() {
// step function over normalized [0,1] == grade 0..10%: band k holds across [k,k+1)%
var p = {}, eps = 0.0009;
for (var k = 0; k < 10; k++) { p[k / 10] = BANDS[k]; p[(k + 1) / 10 - eps] = BANDS[k]; }
p[1] = BANDS[10];
return p;
}
function slopeValue(cur, prev) {
if (!cur || !prev) return 0;
var d = prev.distanceTo(cur); if (!d) return 0;
return Math.abs(100 * (((cur.alt) || 0) - ((prev.alt) || 0)) / d); // |grade %|
}
function applySlopeProvider(ctrl) {
try {
var pr = ctrl && ctrl.providers && ctrl.providers.incline && ctrl.providers.incline.provider;
if (!pr || !pr.hotlineOptions) return false;
pr.hotlineOptions.min = 0;
pr.hotlineOptions.max = 10;
pr.hotlineOptions.palette = slopePalette();
pr.valueFunction = slopeValue;
ctrl._initialProvider = "incline";
ctrl.selectedProvider = "incline";
return true;
} catch (e) { return false; }
}
var rqHooked = false;
function registerRouteQuality() {
if (rqHooked) return;
if (!(window.BR && BR.RoutingPathQuality && BR.RoutingPathQuality.addInitHook)) return;
rqHooked = true;
BR.RoutingPathQuality.addInitHook(function () { applySlopeProvider(this); BR.__quality = this; });
}
// Best-effort: auto-enable the "Route quality" overlay so the route shows slope out of the
// box. Its checkbox label is localized (locale files), so match a few languages; if it
// isn't found the palette override still applies once the user turns it on (button / key C).
function enableRouteQuality() {
try { if (localStorage.getItem("baldav_bw_rq_v1") === "1") return true; } catch (e) {}
var labels = document.querySelectorAll("#layers-control-wrapper label, .leaflet-control-layers-overlays label");
if (!labels.length) return false;
var re = /route.?quality|streckenqualit|качеств/i, done = false;
labels.forEach(function (lab) {
if (!re.test((lab.textContent || ""))) return;
var cb = lab.querySelector("input[type=checkbox]") || lab.control || (lab.htmlFor && document.getElementById(lab.htmlFor));
if (cb && cb.type === "checkbox" && !cb.checked) { cb.click(); }
done = true;
});
if (done) { try { localStorage.setItem("baldav_bw_rq_v1", "1"); } catch (e) {} }
return done;
}
function init() {
registerRouteQuality();
injectStyle();
apply();
var tries = 0;
var iv = setInterval(function () {
tries++;
var b = addButton(); var o = setDefaultOverlays();
if ((b && o) || tries > 60) clearInterval(iv);
// If the control got built before our hook (shouldn't, but be safe), patch it live.
if (window.BR && BR.__quality && !BR.__quality.__baldavSlope) {
if (applySlopeProvider(BR.__quality)) BR.__quality.__baldavSlope = true;
}
var q = enableRouteQuality();
if ((b && o && q) || tries > 60) clearInterval(iv);
}, 500);
}
// Register the route-quality hook AT SCRIPT-EXECUTION TIME (bw.js has already defined
// BR.RoutingPathQuality by now, and the control is only constructed later on DOM ready) —
// so the slope palette is in place before its first draw.
registerRouteQuality();
if (document.readyState !== "loading") init(); else document.addEventListener("DOMContentLoaded", init);
})();