realistic timestamps option

This commit is contained in:
vcoppe
2024-08-29 18:37:06 +02:00
parent 920e7901f4
commit a1b5fe6352
2 changed files with 418 additions and 333 deletions

View File

@@ -350,6 +350,15 @@ export class GPXFile extends GPXTreeNode<Track>{
}); });
} }
createArtificialTimestamps(startTime: Date, totalTime: number, trackIndex?: number, segmentIndex?: number) {
let lastPoint = undefined;
this.trk.forEach((track, index) => {
if (trackIndex === undefined || trackIndex === index) {
track.createArtificialTimestamps(startTime, totalTime, lastPoint, segmentIndex);
}
});
}
setStyle(style: LineStyleExtension) { setStyle(style: LineStyleExtension) {
this.trk.forEach((track) => { this.trk.forEach((track) => {
track.setStyle(style); track.setStyle(style);
@@ -581,6 +590,17 @@ export class Track extends GPXTreeNode<TrackSegment> {
}); });
} }
createArtificialTimestamps(startTime: Date, totalTime: number, lastPoint: TrackPoint | undefined, segmentIndex?: number) {
this.trkseg.forEach((segment, index) => {
if (segmentIndex === undefined || segmentIndex === index) {
segment.createArtificialTimestamps(startTime, totalTime, lastPoint);
if (segment.trkpt.length > 0) {
lastPoint = segment.trkpt[segment.trkpt.length - 1];
}
}
});
}
setStyle(style: LineStyleExtension, force: boolean = true) { setStyle(style: LineStyleExtension, force: boolean = true) {
if (!this.extensions) { if (!this.extensions) {
this.extensions = {}; this.extensions = {};
@@ -944,6 +964,14 @@ export class TrackSegment extends GPXTreeLeaf {
this.trkpt = freeze(trkpt); // Pre-freeze the array, faster as well this.trkpt = freeze(trkpt); // Pre-freeze the array, faster as well
} }
} }
createArtificialTimestamps(startTime: Date, totalTime: number, lastPoint: TrackPoint | undefined) {
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
let slope = og._computeSlope();
let trkpt = withArtificialTimestamps(og.trkpt, totalTime, lastPoint, startTime, slope);
this.trkpt = freeze(trkpt); // Pre-freeze the array, faster as well
}
setHidden(hidden: boolean) { setHidden(hidden: boolean) {
this._data.hidden = hidden; this._data.hidden = hidden;
} }
@@ -1442,6 +1470,30 @@ function withShiftedAndCompressedTimestamps(points: TrackPoint[], speed: number,
}); });
} }
function withArtificialTimestamps(points: TrackPoint[], totalTime: number, lastPoint: TrackPoint | undefined, startTime: Date, slope: number[]): TrackPoint[] {
let weight = [];
let totalWeight = 0;
for (let i = 0; i < points.length - 1; i++) {
let dist = distance(points[i].getCoordinates(), points[i + 1].getCoordinates());
let w = dist * (0.5 + 1 / (1 + Math.exp(- 0.2 * slope[i])));
weight.push(w);
totalWeight += w;
}
let last = lastPoint;
return points.map((point, i) => {
let pt = point.clone();
if (i === 0) {
pt.time = lastPoint?.time ?? startTime;
} else {
pt.time = new Date(last.time.getTime() + totalTime * 1000 * weight[i - 1] / totalWeight);
}
last = pt;
return pt;
});
}
function getTimestamp(a: TrackPoint, b: TrackPoint, speed: number): Date { function getTimestamp(a: TrackPoint, b: TrackPoint, speed: number): Date {
let dist = distance(a.getCoordinates(), b.getCoordinates()) / 1000; let dist = distance(a.getCoordinates(), b.getCoordinates()) / 1000;
return new Date(a.time.getTime() + 1000 * 3600 * dist / speed); return new Date(a.time.getTime() + 1000 * 3600 * dist / speed);

View File

@@ -33,6 +33,7 @@
let endTime: string | undefined = undefined; let endTime: string | undefined = undefined;
let movingTime: number | undefined = undefined; let movingTime: number | undefined = undefined;
let speed: number | undefined = undefined; let speed: number | undefined = undefined;
let artificial = false;
function toCalendarDate(date: Date): CalendarDate { function toCalendarDate(date: Date): CalendarDate {
return new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate()); return new CalendarDate(date.getFullYear(), date.getMonth() + 1, date.getDate());
@@ -281,8 +282,8 @@
/> />
</div> </div>
{#if $gpxStatistics.global.time.moving === 0 || $gpxStatistics.global.time.moving === undefined} {#if $gpxStatistics.global.time.moving === 0 || $gpxStatistics.global.time.moving === undefined}
<div class="mt-0.5 flex flex-row gap-1 items-center hidden"> <div class="mt-0.5 flex flex-row gap-1 items-center">
<Checkbox id="artificial-time" disabled={!canUpdate} /> <Checkbox id="artificial-time" bind:checked={artificial} disabled={!canUpdate} />
<Label for="artificial-time"> <Label for="artificial-time">
{$_('toolbar.time.artificial')} {$_('toolbar.time.artificial')}
</Label> </Label>
@@ -296,7 +297,11 @@
class="grow" class="grow"
on:click={() => { on:click={() => {
let effectiveSpeed = getSpeed(); let effectiveSpeed = getSpeed();
if (startDate === undefined || startTime === undefined || effectiveSpeed === undefined) { if (
startDate === undefined ||
startTime === undefined ||
effectiveSpeed === undefined
) {
return; return;
} }
@@ -316,15 +321,42 @@
let fileId = item.getFileId(); let fileId = item.getFileId();
dbUtils.applyToFile(fileId, (file) => { dbUtils.applyToFile(fileId, (file) => {
if (item instanceof ListFileItem) { if (item instanceof ListFileItem) {
file.changeTimestamps(getDate(startDate, startTime), effectiveSpeed, ratio); if (artificial) {
file.createArtificialTimestamps(
getDate(startDate, startTime),
movingTime
);
} else {
file.changeTimestamps(
getDate(startDate, startTime),
effectiveSpeed,
ratio
);
}
} else if (item instanceof ListTrackItem) { } else if (item instanceof ListTrackItem) {
if (artificial) {
file.createArtificialTimestamps(
getDate(startDate, startTime),
movingTime,
item.getTrackIndex()
);
} else {
file.changeTimestamps( file.changeTimestamps(
getDate(startDate, startTime), getDate(startDate, startTime),
effectiveSpeed, effectiveSpeed,
ratio, ratio,
item.getTrackIndex() item.getTrackIndex()
); );
}
} else if (item instanceof ListTrackSegmentItem) { } else if (item instanceof ListTrackSegmentItem) {
if (artificial) {
file.createArtificialTimestamps(
getDate(startDate, startTime),
movingTime,
item.getTrackIndex(),
item.getSegmentIndex()
);
} else {
file.changeTimestamps( file.changeTimestamps(
getDate(startDate, startTime), getDate(startDate, startTime),
effectiveSpeed, effectiveSpeed,
@@ -333,6 +365,7 @@
item.getSegmentIndex() item.getSegmentIndex()
); );
} }
}
}); });
}} }}
> >