Skip to content

Commit

Permalink
Merge pull request #1294 from jcardus/speed-legend
Browse files Browse the repository at this point in the history
Add speed color legend
  • Loading branch information
tananaev authored Nov 5, 2024
2 parents 92f6457 + ef3d040 commit 6c953ac
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/common/util/colors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Turbo Colormap
const turboPolynomials = {
export const turboPolynomials = {
r: [0.13572138, 4.61539260, -42.66032258, 132.13108234, -152.94239396, 59.28637943],
g: [0.09140261, 2.19418839, 4.84296658, -14.18503333, 4.27729857, 2.82956604],
b: [0.10667330, 12.64194608, -60.58204836, 110.36276771, -89.90310912, 27.34824973],
Expand All @@ -13,7 +13,7 @@ const interpolateChannel = (normalizedValue, coeffs) => {
return Math.max(0, Math.min(1, result));
};

const interpolateTurbo = (value) => {
export const interpolateTurbo = (value) => {
const normalizedValue = Math.max(0, Math.min(1, value));
return [
Math.round(255 * interpolateChannel(normalizedValue, turboPolynomials.r)),
Expand Down
9 changes: 9 additions & 0 deletions src/map/MapRoutePoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ import { useId, useCallback, useEffect } from 'react';
import { map } from './core/MapView';
import getSpeedColor from '../common/util/colors';
import { findFonts } from './core/mapUtil';
import { SpeedLegendControl } from './legend/MapSpeedLegend';
import { useTranslation } from '../common/components/LocalizationProvider';
import { useAttributePreference } from '../common/util/preferences';

const MapRoutePoints = ({ positions, onClick }) => {
const id = useId();
const t = useTranslation();
const speedUnit = useAttributePreference('speedUnit');

const onMouseEnter = () => map.getCanvas().style.cursor = 'pointer';
const onMouseLeave = () => map.getCanvas().style.cursor = '';
Expand Down Expand Up @@ -62,6 +67,9 @@ const MapRoutePoints = ({ positions, onClick }) => {
const maxSpeed = positions.map((p) => p.speed).reduce((a, b) => Math.max(a, b), -Infinity);
const minSpeed = positions.map((p) => p.speed).reduce((a, b) => Math.min(a, b), Infinity);

const control = new SpeedLegendControl(positions, speedUnit, t, maxSpeed, minSpeed);
map.addControl(control, 'bottom-left');

map.getSource(id)?.setData({
type: 'FeatureCollection',
features: positions.map((position, index) => ({
Expand All @@ -78,6 +86,7 @@ const MapRoutePoints = ({ positions, onClick }) => {
},
})),
});
return () => map.removeControl(control);
}, [onMarkerClick, positions]);

return null;
Expand Down
57 changes: 57 additions & 0 deletions src/map/legend/MapSpeedLegend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { interpolateTurbo } from '../../common/util/colors';
import { speedFromKnots, speedUnitString } from '../../common/util/converter';

export class SpeedLegendControl {
constructor(positions, speedUnit, t, maxSpeed, minSpeed) {
this.positions = positions;
this.t = t;
this.speedUnit = speedUnit;
this.maxSpeed = maxSpeed;
this.minSpeed = minSpeed;
}

onAdd(map) {
this.map = map;
this.controlContainer = document.createElement('div');
this.controlContainer.className = 'maplibregl-ctrl maplibregl-ctrl-scale';

if (this.positions.length && this.maxSpeed) {
this.controlContainer.appendChild(this.createSpeedLegend());
}

return this.controlContainer;
}

onRemove() {
if (this.controlContainer && this.controlContainer.parentNode) {
this.controlContainer.parentNode.removeChild(this.controlContainer);
this.map = undefined;
}
}

createSpeedLegend() {
const gradientStops = Array.from({ length: 10 }, (_, i) => {
const t = i / 9;
const [r, g, b] = interpolateTurbo(t);
return `rgb(${r}, ${g}, ${b})`;
}).join(', ');

const legend = document.createElement('div');

const colorBar = document.createElement('div');
colorBar.style.background = `linear-gradient(to right, ${gradientStops})`;
colorBar.style.height = '10px';

const speedLabel = document.createElement('span');
const minSpeed = Math.round(speedFromKnots(this.minSpeed, this.speedUnit));
const maxSpeed = Math.round(speedFromKnots(this.maxSpeed, this.speedUnit));
speedLabel.textContent = `${minSpeed} - ${maxSpeed} ${speedUnitString(this.speedUnit, this.t)}`;

legend.appendChild(colorBar);
legend.appendChild(speedLabel);

return legend;
}
}

export default SpeedLegendControl;

0 comments on commit 6c953ac

Please sign in to comment.