This commit is contained in:
vcoppe
2026-10-04 19:14:41 +02:00
parent c536e6247b
commit 5e2f506120
19 changed files with 484 additions and 47 deletions
@@ -25,6 +25,7 @@ import type { Coordinates } from 'gpx';
import { NO_TIME, type SelectionStatistics } from '$lib/engine';
import type { SlicedStatistics } from '$lib/logic/selection-statistics';
import { mode } from 'mode-watcher';
import { categoryAt } from '$lib/trackpoint-categories';
import { getHighwayColor, getSlopeColor, getSurfaceColor } from '$lib/assets/colors';
const { distanceUnits, velocityUnits, temperatureUnits } = settings;
@@ -41,7 +42,8 @@ interface ElevationProfilePoint {
segment: number;
length: number;
};
extensions: Record<string, any>;
surface?: string;
highway?: string;
coordinates: Coordinates;
index: number;
}
@@ -185,14 +187,11 @@ export class ElevationProfile {
segment: point.slope.segment.toFixed(1),
length: getDistanceWithUnits(point.slope.length),
};
let surface = point.extensions.surface
? point.extensions.surface
: 'unknown';
let highway = point.extensions.highway
? point.extensions.highway
: 'unknown';
let sacScale = point.extensions.sac_scale;
let mtbScale = point.extensions.mtb_scale;
let surface = point.surface ?? 'unknown';
let highway = point.highway ?? 'unknown';
// TODO the engine does not store the sac and mtb scales yet
let sacScale: string | undefined = undefined;
let mtbScale: string | undefined = undefined;
let labels = [
` ${i18n._('quantities.distance')}: ${getDistanceWithUnits(point.x, false)}`,
@@ -413,8 +412,8 @@ export class ElevationProfile {
segment: data.slopeSegmentSlope[index],
length: data.slopeSegmentDistance[index],
},
// TODO the engine does not store the extensions (surface, highway...) yet
extensions: data.extensions[index] ?? {},
surface: categoryAt(data.surface, data.surfaces, index),
highway: categoryAt(data.highway, data.highways, index),
coordinates: { lat: data.lat[index], lon: data.lng[index] },
index,
});
@@ -602,16 +601,13 @@ export class ElevationProfile {
surfaceFillCallback(context: ScriptableLineSegmentContext & { p0: { raw: any } }) {
const point = context.p0.raw as ElevationProfilePoint;
return getSurfaceColor(point.extensions.surface);
return getSurfaceColor(point.surface ?? '');
}
highwayFillCallback(context: ScriptableLineSegmentContext & { p0: { raw: any } }) {
const point = context.p0.raw as ElevationProfilePoint;
return getHighwayColor(
point.extensions.highway,
point.extensions.sac_scale,
point.extensions.mtb_scale
);
// TODO the engine does not store the sac and mtb scales yet
return getHighwayColor(point.highway ?? '', undefined, undefined);
}
destroy() {
+16 -7
View File
@@ -140,11 +140,14 @@ export type SelectionStatistics = {
cad: Float64Array;
atemp: Float64Array;
power: Float64Array;
/**
* Extensions of the trackpoints (surface, highway...), or an empty array when they are not
* known. TODO the engine does not store them yet.
*/
extensions: Record<string, string>[];
/** Surface of the trackpoints: 0 when unknown, else 1 + the index in `surfaces`. */
surface: Uint8Array;
/** Names of the surfaces, by code: a name keeps its index. */
surfaces: string[];
/** Highway of the trackpoints: 0 when unknown, else 1 + the index in `highways`. */
highway: Uint8Array;
/** Names of the highways, by code. */
highways: string[];
/**
* Global statistics of the trackpoints from `start` to `end` (both included), for example
* the part of the elevation profile that was dragged over. `undefined` if the range is not
@@ -174,7 +177,10 @@ const EMPTY_SELECTION_STATISTICS: SelectionStatistics = {
cad: new Float64Array(),
atemp: new Float64Array(),
power: new Float64Array(),
extensions: [],
surface: new Uint8Array(),
surfaces: [],
highway: new Uint8Array(),
highways: [],
slice: () => undefined,
};
@@ -625,7 +631,10 @@ class Engine {
cad: wasm.cad().slice(),
atemp: wasm.atemp().slice(),
power: wasm.power().slice(),
extensions: [],
surface: wasm.surface().slice(),
surfaces: wasm.surfaces(),
highway: wasm.highway().slice(),
highways: wasm.highways(),
slice: (start, end) =>
version === this._statisticsVersion ? wasm.slice_statistics(start, end) : undefined,
};
@@ -0,0 +1,24 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { categoryAt } from './trackpoint-categories';
describe('categoryAt', () => {
const codes = new Uint8Array([1, 1, 0, 2, 0]);
const names = ['asphalt', 'gravel'];
it('is the name of the code', () => {
assert.equal(categoryAt(codes, names, 0), 'asphalt');
assert.equal(categoryAt(codes, names, 3), 'gravel');
});
it('is undefined when the value is unknown', () => {
assert.equal(categoryAt(codes, names, 2), undefined);
assert.equal(categoryAt(codes, names, 4), undefined);
});
it('is undefined out of the trackpoints, or for a code without name', () => {
assert.equal(categoryAt(codes, names, 5), undefined);
assert.equal(categoryAt(new Uint8Array([3]), names, 0), undefined);
assert.equal(categoryAt(new Uint8Array(), [], 0), undefined);
});
});
+12
View File
@@ -0,0 +1,12 @@
/**
* The value of a trackpoint for a category of the engine (surface, highway): `codes` has one entry
* per trackpoint, 0 when the value is unknown, else 1 + the index of the value in `names`.
*/
export function categoryAt(
codes: ArrayLike<number>,
names: readonly string[],
index: number
): string | undefined {
const code = codes[index];
return code ? names[code - 1] : undefined;
}
+4 -1
View File
@@ -45,7 +45,10 @@
cad: new Float64Array(),
atemp: new Float64Array(),
power: new Float64Array(),
extensions: [],
surface: new Uint8Array(),
surfaces: [],
highway: new Uint8Array(),
highways: [],
slice: () => undefined,
});
let slicedStatistics = writable(undefined);