fix surface

This commit is contained in:
vcoppe
2024-09-22 13:05:28 +02:00
parent 5592cf47e0
commit 56e4522da7
3 changed files with 43 additions and 12 deletions

View File

@@ -774,6 +774,14 @@ export class TrackSegment extends GPXTreeLeaf {
statistics.global.power.count++; statistics.global.power.count++;
} }
} }
if (i > 0 && points[i - 1].extensions && points[i - 1].extensions["gpxtpx:TrackPointExtension"] && points[i - 1].extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"] && points[i - 1].extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"].surface) {
let surface = points[i - 1].extensions["gpxtpx:TrackPointExtension"]["gpxtpx:Extensions"].surface;
if (statistics.global.surface[surface] === undefined) {
statistics.global.surface[surface] = 0;
}
statistics.global.surface[surface] += dist;
}
} }
[statistics.local.slope.segment, statistics.local.slope.length] = this._computeSlopeSegments(statistics); [statistics.local.slope.segment, statistics.local.slope.length] = this._computeSlopeSegments(statistics);
@@ -887,22 +895,30 @@ export class TrackSegment extends GPXTreeLeaf {
let trkpt = og.trkpt.slice(); let trkpt = og.trkpt.slice();
if (speed !== undefined || (trkpt.length > 0 && trkpt[0].time !== undefined)) { if (speed !== undefined || (trkpt.length > 0 && trkpt[0].time !== undefined)) {
// Must handle timestamps (either segment has timestamps or the new points will have timestamps)
if (start > 0 && trkpt[0].time === undefined) { if (start > 0 && trkpt[0].time === undefined) {
// Add timestamps to points before [start, end] because they are missing
trkpt.splice(0, 0, ...withTimestamps(trkpt.splice(0, start), speed, undefined, startTime)); trkpt.splice(0, 0, ...withTimestamps(trkpt.splice(0, start), speed, undefined, startTime));
} }
if (points.length > 0) { if (points.length > 0) {
// Adapt timestamps of the new points
let last = start > 0 ? trkpt[start - 1] : undefined; let last = start > 0 ? trkpt[start - 1] : undefined;
if (points[0].time === undefined || (points.length > 1 && points[1].time === undefined)) { if (points[0].time === undefined || (points.length > 1 && points[1].time === undefined)) {
// Add timestamps to the new points because they are missing
points = withTimestamps(points, speed, last, startTime); points = withTimestamps(points, speed, last, startTime);
} else if (last !== undefined && points[0].time < last.time) { } else if (last !== undefined && points[0].time < last.time) {
// Adapt timestamps of the new points because they are too early
points = withShiftedAndCompressedTimestamps(points, speed, 1, last); points = withShiftedAndCompressedTimestamps(points, speed, 1, last);
} }
} }
if (end < trkpt.length - 1) { if (end < trkpt.length - 1) {
// Adapt timestamps of points after [start, end]
let last = points.length > 0 ? points[points.length - 1] : start > 0 ? trkpt[start - 1] : undefined; let last = points.length > 0 ? points[points.length - 1] : start > 0 ? trkpt[start - 1] : undefined;
if (trkpt[end + 1].time === undefined) { if (trkpt[end + 1].time === undefined) {
// Add timestamps to points after [start, end] because they are missing
trkpt.splice(end + 1, 0, ...withTimestamps(trkpt.splice(end + 1), speed, last, startTime)); trkpt.splice(end + 1, 0, ...withTimestamps(trkpt.splice(end + 1), speed, last, startTime));
} else if (last !== undefined && trkpt[end + 1].time < last.time) { } else if (last !== undefined && trkpt[end + 1].time < last.time) {
// Adapt timestamps of points after [start, end] because they are too early
trkpt.splice(end + 1, 0, ...withShiftedAndCompressedTimestamps(trkpt.splice(end + 1), speed, 1, last)); trkpt.splice(end + 1, 0, ...withShiftedAndCompressedTimestamps(trkpt.splice(end + 1), speed, 1, last));
} }
} }
@@ -1238,7 +1254,8 @@ export class GPXStatistics {
power: { power: {
avg: number, avg: number,
count: number, count: number,
} },
surface: Record<string, number>,
}; };
local: { local: {
points: TrackPoint[], points: TrackPoint[],
@@ -1308,7 +1325,8 @@ export class GPXStatistics {
power: { power: {
avg: 0, avg: 0,
count: 0, count: 0,
} },
surface: {},
}; };
this.local = { this.local = {
points: [], points: [],
@@ -1378,6 +1396,12 @@ export class GPXStatistics {
this.global.cad.count += other.global.cad.count; this.global.cad.count += other.global.cad.count;
this.global.power.avg = (this.global.power.count * this.global.power.avg + other.global.power.count * other.global.power.avg) / Math.max(1, this.global.power.count + other.global.power.count); this.global.power.avg = (this.global.power.count * this.global.power.avg + other.global.power.count * other.global.power.avg) / Math.max(1, this.global.power.count + other.global.power.count);
this.global.power.count += other.global.power.count; this.global.power.count += other.global.power.count;
Object.keys(other.global.surface).forEach((surface) => {
if (this.global.surface[surface] === undefined) {
this.global.surface[surface] = 0;
}
this.global.surface[surface] += other.global.surface[surface];
});
} }
slice(start: number, end: number): GPXStatistics { slice(start: number, end: number): GPXStatistics {

View File

@@ -63,6 +63,7 @@
} }
hide.time = statistics.global.time.total === 0; hide.time = statistics.global.time.total === 0;
hide.surface = !Object.keys(statistics.global.surface).some((key) => key !== 'unknown');
hide.hr = statistics.global.hr.count === 0; hide.hr = statistics.global.hr.count === 0;
hide.cad = statistics.global.cad.count === 0; hide.cad = statistics.global.cad.count === 0;
hide.atemp = statistics.global.atemp.count === 0; hide.atemp = statistics.global.atemp.count === 0;
@@ -86,10 +87,10 @@
class="fixed left-[50%] top-[50%] z-50 w-fit max-w-full translate-x-[-50%] translate-y-[-50%] flex flex-col items-center gap-3 border bg-background p-3 shadow-lg rounded-md" class="fixed left-[50%] top-[50%] z-50 w-fit max-w-full translate-x-[-50%] translate-y-[-50%] flex flex-col items-center gap-3 border bg-background p-3 shadow-lg rounded-md"
> >
<div <div
class="w-full flex flex-row items-center justify-center gap-4 border rounded-md p-2 bg-accent" class="w-full flex flex-row items-center justify-center gap-4 border rounded-md p-2 bg-secondary"
> >
<span>⚠️</span> <span>⚠️</span>
<span class="max-w-96 text-sm"> <span class="max-w-[80%] text-sm">
{$_('menu.support_message')} {$_('menu.support_message')}
</span> </span>
</div> </div>
@@ -119,7 +120,11 @@
{/if} {/if}
</Button> </Button>
</div> </div>
<div class="w-full max-w-xl flex flex-col items-center gap-2"> <div
class="w-full max-w-xl flex flex-col items-center gap-2 {Object.values(hide).some((v) => !v)
? ''
: 'hidden'}"
>
<div class="w-full flex flex-row items-center gap-3"> <div class="w-full flex flex-row items-center gap-3">
<div class="grow"> <div class="grow">
<Separator /> <Separator />
@@ -139,7 +144,7 @@
{$_('quantities.time')} {$_('quantities.time')}
</Label> </Label>
</div> </div>
<div class="flex flex-row items-center gap-1.5"> <div class="flex flex-row items-center gap-1.5 {hide.surface ? 'hidden' : ''}">
<Checkbox id="export-surface" bind:checked={exportOptions.surface} /> <Checkbox id="export-surface" bind:checked={exportOptions.surface} />
<Label for="export-surface" class="flex flex-row items-center gap-1"> <Label for="export-surface" class="flex flex-row items-center gap-1">
<BrickWall size="16" /> <BrickWall size="16" />

View File

@@ -66,7 +66,7 @@ async function getRoute(points: Coordinates[], brouterProfile: string, privateRo
const latIdx = messages[0].indexOf("Latitude"); const latIdx = messages[0].indexOf("Latitude");
const tagIdx = messages[0].indexOf("WayTags"); const tagIdx = messages[0].indexOf("WayTags");
let messageIdx = 1; let messageIdx = 1;
let surface = messageIdx < messages.length ? getSurface(messages[messageIdx][tagIdx]) : "unknown"; let surface = messageIdx < messages.length ? getSurface(messages[messageIdx][tagIdx]) : undefined;
for (let i = 0; i < coordinates.length; i++) { for (let i = 0; i < coordinates.length; i++) {
let coord = coordinates[i]; let coord = coordinates[i];
@@ -77,27 +77,30 @@ async function getRoute(points: Coordinates[], brouterProfile: string, privateRo
}, },
ele: coord[2] ?? (i > 0 ? route[i - 1].ele : 0) ele: coord[2] ?? (i > 0 ? route[i - 1].ele : 0)
})); }));
route[route.length - 1].setSurface(surface)
if (messageIdx < messages.length && if (messageIdx < messages.length &&
coordinates[i][0] == Number(messages[messageIdx][lngIdx]) / 1000000 && coordinates[i][0] == Number(messages[messageIdx][lngIdx]) / 1000000 &&
coordinates[i][1] == Number(messages[messageIdx][latIdx]) / 1000000) { coordinates[i][1] == Number(messages[messageIdx][latIdx]) / 1000000) {
messageIdx++; messageIdx++;
if (messageIdx == messages.length) surface = "unknown"; if (messageIdx == messages.length) surface = undefined;
else surface = getSurface(messages[messageIdx][tagIdx]); else surface = getSurface(messages[messageIdx][tagIdx]);
} }
if (surface) {
route[route.length - 1].setSurface(surface);
}
} }
return route; return route;
} }
function getSurface(message: string): string { function getSurface(message: string): string | undefined {
const fields = message.split(" "); const fields = message.split(" ");
for (let i = 0; i < fields.length; i++) if (fields[i].startsWith("surface=")) { for (let i = 0; i < fields.length; i++) if (fields[i].startsWith("surface=")) {
return fields[i].substring(8); return fields[i].substring(8);
} }
return "unknown"; return undefined;
}; };
function getIntermediatePoints(points: Coordinates[]): Promise<TrackPoint[]> { function getIntermediatePoints(points: Coordinates[]): Promise<TrackPoint[]> {
@@ -127,7 +130,6 @@ function getIntermediatePoints(points: Coordinates[]): Promise<TrackPoint[]> {
return getElevation(route).then((elevations) => { return getElevation(route).then((elevations) => {
route.forEach((point, i) => { route.forEach((point, i) => {
point.setSurface("unknown");
point.ele = elevations[i]; point.ele = elevations[i];
}); });
return route; return route;