mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-08-31 23:53:25 +00:00
highway, sac_scale and mtb:scale coloring
This commit is contained in:
@@ -25,40 +25,137 @@ export const surfaceColors: { [key: string]: string } = {
|
|||||||
"stone": "#ffd991",
|
"stone": "#ffd991",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getSurfaceColor(surface: string): string {
|
||||||
|
return surfaceColors[surface] ? surfaceColors[surface] : surfaceColors.missing;
|
||||||
|
}
|
||||||
|
|
||||||
export const highwayColors: { [key: string]: string } = {
|
export const highwayColors: { [key: string]: string } = {
|
||||||
"missing": "#d1d1d1",
|
"missing": "#d1d1d1",
|
||||||
"residential": "#73b2ff",
|
|
||||||
"service": "#b3b3cc",
|
|
||||||
"track": "#946f43",
|
|
||||||
"unclassified": "#e0e0e0",
|
|
||||||
"footway": "#a3c989",
|
|
||||||
"tertiary": "#ffdd7f",
|
|
||||||
"path": "#a3c989",
|
|
||||||
"secondary": "#ffd75f",
|
|
||||||
"primary": "#ff6e5c",
|
|
||||||
"cycleway": "#ffbb6e",
|
|
||||||
"trunk": "#ff5e4d",
|
|
||||||
"living_street": "#9de2ff",
|
|
||||||
"motorway": "#ff4d33",
|
"motorway": "#ff4d33",
|
||||||
"motorway_link": "#ff947f",
|
"motorway_link": "#ff4d33",
|
||||||
"steps": "#8d91a2",
|
"trunk": "#ff5e4d",
|
||||||
"road": "#e0e0e0",
|
|
||||||
"pedestrian": "#c1c8e4",
|
|
||||||
"trunk_link": "#ff947f",
|
"trunk_link": "#ff947f",
|
||||||
"primary_link": "#ff8d7b",
|
"primary": "#ff6e5c",
|
||||||
"secondary_link": "#ffcb66",
|
"primary_link": "#ff6e5c",
|
||||||
"tertiary_link": "#ffdd8b",
|
"secondary": "#ff8d7b",
|
||||||
|
"secondary_link": "#ff8d7b",
|
||||||
|
"tertiary": "#ffd75f",
|
||||||
|
"tertiary_link": "#ffd75f",
|
||||||
|
"unclassified": "#f1f2a5",
|
||||||
|
"road": "#f1f2a5",
|
||||||
|
"residential": "#73b2ff",
|
||||||
|
"living_street": "#73b2ff",
|
||||||
|
"service": "#9c9cd9",
|
||||||
|
"track": "#a8e381",
|
||||||
|
"footway": "#a8e381",
|
||||||
|
"path": "#a8e381",
|
||||||
|
"pedestrian": "#a8e381",
|
||||||
|
"cycleway": "#9de2ff",
|
||||||
"construction": "#e09a4a",
|
"construction": "#e09a4a",
|
||||||
"bridleway": "#a3c989",
|
"bridleway": "#946f43",
|
||||||
"platform": "#c4c4c4",
|
|
||||||
"proposed": "#e0e0e0",
|
|
||||||
"raceway": "#ff0000",
|
"raceway": "#ff0000",
|
||||||
"rest_area": "#73b2ff",
|
"rest_area": "#9c9cd9",
|
||||||
"abandoned": "#e0e0e0",
|
"services": "#9c9cd9",
|
||||||
"services": "#ffe066",
|
"corridor": "#474747",
|
||||||
"corridor": "#c4c4c4",
|
"elevator": "#474747",
|
||||||
"bus_stop": "#ffe6e6",
|
"steps": "#474747",
|
||||||
"busway": "#ffe6e6",
|
"bus_stop": "#8545a3",
|
||||||
"elevator": "#c4c4c4",
|
"busway": "#8545a3",
|
||||||
"via_ferrata": "#8d91a2"
|
"via_ferrata": "#474747"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const sacScaleColors: { [key: string]: string } = {
|
||||||
|
"hiking": "#007700",
|
||||||
|
"mountain_hiking": "#1843ad",
|
||||||
|
"demanding_mountain_hiking": "#ffff00",
|
||||||
|
"alpine_hiking": "#ff9233",
|
||||||
|
"demanding_alpine_hiking": "#ff0000",
|
||||||
|
"difficult_alpine_hiking": "#000000",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mtbScaleColors: { [key: string]: string } = {
|
||||||
|
"0-": "#007700",
|
||||||
|
"0": "#007700",
|
||||||
|
"0+": "#007700",
|
||||||
|
"1-": "#1843ad",
|
||||||
|
"1": "#1843ad",
|
||||||
|
"1+": "#1843ad",
|
||||||
|
"2-": "#ffff00",
|
||||||
|
"2": "#ffff00",
|
||||||
|
"2+": "#ffff00",
|
||||||
|
"3": "#ff0000",
|
||||||
|
"4": "#00ff00",
|
||||||
|
"5": "#000000",
|
||||||
|
"6": "#b105eb",
|
||||||
|
};
|
||||||
|
|
||||||
|
function createPattern(backgroundColor: string, sacScaleColor: string | undefined, mtbScaleColor: string | undefined, size: number = 16, lineWidth: number = 4) {
|
||||||
|
let canvas = document.createElement('canvas');
|
||||||
|
canvas.width = size;
|
||||||
|
canvas.height = size;
|
||||||
|
let ctx = canvas.getContext('2d');
|
||||||
|
if (ctx) {
|
||||||
|
ctx.fillStyle = backgroundColor;
|
||||||
|
ctx.fillRect(0, 0, size, size);
|
||||||
|
ctx.lineWidth = lineWidth;
|
||||||
|
|
||||||
|
const halfSize = size / 2;
|
||||||
|
const halfLineWidth = lineWidth / 2;
|
||||||
|
if (sacScaleColor) {
|
||||||
|
ctx.strokeStyle = sacScaleColor;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(halfSize - halfLineWidth, - halfLineWidth);
|
||||||
|
ctx.lineTo(size + halfLineWidth, halfSize + halfLineWidth);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(- halfLineWidth, halfSize - halfLineWidth);
|
||||||
|
ctx.lineTo(halfSize + halfLineWidth, size + halfLineWidth);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
if (mtbScaleColor) {
|
||||||
|
ctx.strokeStyle = mtbScaleColor;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(halfSize - halfLineWidth, size + halfLineWidth);
|
||||||
|
ctx.lineTo(size + halfLineWidth, halfSize - halfLineWidth);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(- halfLineWidth, halfSize + halfLineWidth);
|
||||||
|
ctx.lineTo(halfSize + halfLineWidth, - halfLineWidth);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctx?.createPattern(canvas, 'repeat') || backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const patterns: Record<string, string | CanvasPattern> = {};
|
||||||
|
export function getHighwayColor(highway: string, sacScale: string | undefined, mtbScale: string | undefined) {
|
||||||
|
let backgroundColor = highwayColors[highway] ? highwayColors[highway] : highwayColors.missing;
|
||||||
|
let sacScaleColor = sacScale ? sacScaleColors[sacScale] : undefined;
|
||||||
|
let mtbScaleColor = mtbScale ? mtbScaleColors[mtbScale] : undefined;
|
||||||
|
if (sacScale || mtbScale) {
|
||||||
|
let patternId = `${backgroundColor}-${[sacScale, mtbScale].filter(x => x).join('-')}`;
|
||||||
|
if (!patterns[patternId]) {
|
||||||
|
patterns[patternId] = createPattern(backgroundColor, sacScaleColor, mtbScaleColor);
|
||||||
|
}
|
||||||
|
return patterns[patternId];
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxSlope = 20;
|
||||||
|
export function getSlopeColor(slope: number): string {
|
||||||
|
if (slope > maxSlope) {
|
||||||
|
slope = maxSlope;
|
||||||
|
} else if (slope < -maxSlope) {
|
||||||
|
slope = -maxSlope;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v = slope / maxSlope;
|
||||||
|
v = 1 / (1 + Math.exp(-6 * v));
|
||||||
|
v = v - 0.5;
|
||||||
|
|
||||||
|
let hue = ((0.5 - v) * 120).toString(10);
|
||||||
|
let lightness = 90 - Math.abs(v) * 70;
|
||||||
|
|
||||||
|
return `hsl(${hue},70%,${lightness}%)`;
|
||||||
|
}
|
@@ -19,7 +19,7 @@
|
|||||||
ChartNoAxesColumn,
|
ChartNoAxesColumn,
|
||||||
Construction
|
Construction
|
||||||
} from 'lucide-svelte';
|
} from 'lucide-svelte';
|
||||||
import { surfaceColors, highwayColors } from '$lib/assets/colors';
|
import { getSlopeColor, getSurfaceColor, getHighwayColor } from '$lib/assets/colors';
|
||||||
import { _, locale } from 'svelte-i18n';
|
import { _, locale } from 'svelte-i18n';
|
||||||
import {
|
import {
|
||||||
getCadenceWithUnits,
|
getCadenceWithUnits,
|
||||||
@@ -443,33 +443,20 @@
|
|||||||
chart.update();
|
chart.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
let maxSlope = 20;
|
|
||||||
function slopeFillCallback(context) {
|
function slopeFillCallback(context) {
|
||||||
let slope = context.p0.raw.slope.segment;
|
return getSlopeColor(context.p0.raw.slope.segment);
|
||||||
if (slope > maxSlope) {
|
|
||||||
slope = maxSlope;
|
|
||||||
} else if (slope < -maxSlope) {
|
|
||||||
slope = -maxSlope;
|
|
||||||
}
|
|
||||||
|
|
||||||
let v = slope / maxSlope;
|
|
||||||
v = 1 / (1 + Math.exp(-6 * v));
|
|
||||||
v = v - 0.5;
|
|
||||||
|
|
||||||
let hue = ((0.5 - v) * 120).toString(10);
|
|
||||||
let lightness = 90 - Math.abs(v) * 70;
|
|
||||||
|
|
||||||
return ['hsl(', hue, ',70%,', lightness, '%)'].join('');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function surfaceFillCallback(context) {
|
function surfaceFillCallback(context) {
|
||||||
let surface = context.p0.raw.extensions.surface;
|
return getSurfaceColor(context.p0.raw.extensions.surface);
|
||||||
return surfaceColors[surface] ? surfaceColors[surface] : surfaceColors.missing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function highwayFillCallback(context) {
|
function highwayFillCallback(context) {
|
||||||
let highway = context.p0.raw.extensions.highway;
|
return getHighwayColor(
|
||||||
return highwayColors[highway] ? highwayColors[highway] : highwayColors.missing;
|
context.p0.raw.extensions.highway,
|
||||||
|
context.p0.raw.extensions.sac_scale,
|
||||||
|
context.p0.raw.extensions['mtb:scale']
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (chart) {
|
$: if (chart) {
|
||||||
|
Reference in New Issue
Block a user