Format with eslint

This commit is contained in:
Anthony DePasquale 2025-02-25 11:58:01 +01:00
parent 24ffdb5d9c
commit a2cd6ee681
24 changed files with 479 additions and 483 deletions

View file

@ -1,11 +1,7 @@
/** @type { import("eslint").Linter.Config } */
module.exports = {
root: true,
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
@ -17,4 +13,4 @@ module.exports = {
es2017: true,
node: true,
},
};
};

View file

@ -74,8 +74,8 @@ abstract class GPXTreeNode<T extends GPXTreeElement<any>> extends GPXTreeElement
}
getStatistics(): GPXStatistics {
let statistics = new GPXStatistics();
for (let child of this.children) {
const statistics = new GPXStatistics();
for (const child of this.children) {
statistics.mergeWith(child.getStatistics());
}
return statistics;
@ -91,7 +91,7 @@ abstract class GPXTreeNode<T extends GPXTreeElement<any>> extends GPXTreeElement
// Producers
_reverse(originalNextTimestamp?: Date, newPreviousTimestamp?: Date) {
let og = getOriginal(this);
const og = getOriginal(this);
if (!originalNextTimestamp && !newPreviousTimestamp) {
originalNextTimestamp = og.getEndTimestamp();
newPreviousTimestamp = og.getStartTimestamp();
@ -100,7 +100,7 @@ abstract class GPXTreeNode<T extends GPXTreeElement<any>> extends GPXTreeElement
this.children.reverse();
for (let i = 0; i < og.children.length; i++) {
let originalStartTimestamp =
const originalStartTimestamp =
og.children[og.children.length - i - 1].getStartTimestamp();
this.children[i]._reverse(originalNextTimestamp, newPreviousTimestamp);
@ -154,8 +154,8 @@ export class GPXFile extends GPXTreeNode<Track> {
this._data = gpx._data;
}
if (!this._data.hasOwnProperty('style')) {
let style = this.getStyle();
let fileStyle = {};
const style = this.getStyle();
const fileStyle = {};
if (style.color.length === 1) {
fileStyle['gpx_style:color'] = style.color[0];
}
@ -263,7 +263,7 @@ export class GPXFile extends GPXTreeNode<Track> {
}
toGPXFileType(exclude: string[] = []): GPXFileType {
let file: GPXFileType = {
const file: GPXFileType = {
attributes: cloneJSON(this.attributes),
metadata: {},
wpt: this.wpt.map((wpt) => wpt.toWaypointType(exclude)),
@ -348,7 +348,7 @@ export class GPXFile extends GPXTreeNode<Track> {
let i = 0;
let trackIndex = 0;
while (i < this.trk.length) {
let length = this.trk[i].getNumberOfTrackPoints();
const length = this.trk[i].getNumberOfTrackPoints();
if (trackIndices === undefined || trackIndices.includes(trackIndex)) {
if (start >= length || end < 0) {
this.trk.splice(i, 1);
@ -398,10 +398,10 @@ export class GPXFile extends GPXTreeNode<Track> {
}
}
if (deleteWaypoints) {
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
let wpt = og.wpt.filter((point, waypointIndex) => {
const og = getOriginal(this); // Read as much as possible from the original object because it is faster
const wpt = og.wpt.filter((point, waypointIndex) => {
if (waypointIndices === undefined || waypointIndices.includes(waypointIndex)) {
let inBounds =
const inBounds =
point.attributes.lat >= bounds[0].lat &&
point.attributes.lat <= bounds[1].lat &&
point.attributes.lon >= bounds[0].lon &&
@ -422,7 +422,7 @@ export class GPXFile extends GPXTreeNode<Track> {
trackIndex?: number,
segmentIndex?: number
) {
let lastPoint = undefined;
const lastPoint = undefined;
this.trk.forEach((track, index) => {
if (trackIndex === undefined || trackIndex === index) {
track.changeTimestamps(startTime, speed, ratio, lastPoint, segmentIndex);
@ -436,7 +436,7 @@ export class GPXFile extends GPXTreeNode<Track> {
trackIndex?: number,
segmentIndex?: number
) {
let lastPoint = undefined;
const lastPoint = undefined;
this.trk.forEach((track, index) => {
if (trackIndex === undefined || trackIndex === index) {
track.createArtificialTimestamps(startTime, totalTime, lastPoint, segmentIndex);
@ -608,7 +608,7 @@ export class Track extends GPXTreeNode<TrackSegment> {
toGeoJSON(): GeoJSON.Feature[] {
return this.children.map((child) => {
let geoJSON = child.toGeoJSON();
const geoJSON = child.toGeoJSON();
if (this.extensions && this.extensions['gpx_style:line']) {
if (this.extensions['gpx_style:line']['gpx_style:color']) {
geoJSON.properties['color'] =
@ -682,7 +682,7 @@ export class Track extends GPXTreeNode<TrackSegment> {
let i = 0;
let segmentIndex = 0;
while (i < this.trkseg.length) {
let length = this.trkseg[i].getNumberOfTrackPoints();
const length = this.trkseg[i].getNumberOfTrackPoints();
if (segmentIndices === undefined || segmentIndices.includes(segmentIndex)) {
if (start >= length || end < 0) {
this.trkseg.splice(i, 1);
@ -814,7 +814,7 @@ export class TrackSegment extends GPXTreeLeaf {
}
_computeStatistics(): GPXStatistics {
let statistics = new GPXStatistics();
const statistics = new GPXStatistics();
statistics.local.points = this.trkpt.map((point) => point);
@ -902,7 +902,7 @@ export class TrackSegment extends GPXTreeLeaf {
points[i].extensions['gpxtpx:TrackPointExtension'] &&
points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:atemp']
) {
let atemp = points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:atemp'];
const atemp = points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:atemp'];
statistics.global.atemp.avg =
(statistics.global.atemp.count * statistics.global.atemp.avg + atemp) /
(statistics.global.atemp.count + 1);
@ -912,7 +912,7 @@ export class TrackSegment extends GPXTreeLeaf {
points[i].extensions['gpxtpx:TrackPointExtension'] &&
points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:hr']
) {
let hr = points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:hr'];
const hr = points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:hr'];
statistics.global.hr.avg =
(statistics.global.hr.count * statistics.global.hr.avg + hr) /
(statistics.global.hr.count + 1);
@ -922,7 +922,7 @@ export class TrackSegment extends GPXTreeLeaf {
points[i].extensions['gpxtpx:TrackPointExtension'] &&
points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:cad']
) {
let cad = points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:cad'];
const cad = points[i].extensions['gpxtpx:TrackPointExtension']['gpxtpx:cad'];
statistics.global.cad.avg =
(statistics.global.cad.count * statistics.global.cad.avg + cad) /
(statistics.global.cad.count + 1);
@ -932,7 +932,7 @@ export class TrackSegment extends GPXTreeLeaf {
points[i].extensions['gpxpx:PowerExtension'] &&
points[i].extensions['gpxpx:PowerExtension']['gpxpx:PowerInWatts']
) {
let power = points[i].extensions['gpxpx:PowerExtension']['gpxpx:PowerInWatts'];
const power = points[i].extensions['gpxpx:PowerExtension']['gpxpx:PowerInWatts'];
statistics.global.power.avg =
(statistics.global.power.count * statistics.global.power.avg + power) /
(statistics.global.power.count + 1);
@ -993,7 +993,7 @@ export class TrackSegment extends GPXTreeLeaf {
_computeSmoothedElevation(): number[] {
const points = this.trkpt;
let smoothed = distanceWindowSmoothing(
const smoothed = distanceWindowSmoothing(
points,
100,
(index) => points[index].ele ?? 0,
@ -1021,21 +1021,21 @@ export class TrackSegment extends GPXTreeLeaf {
}
_computeSlopeSegments(statistics: GPXStatistics): [number[], number[]] {
let simplified = ramerDouglasPeucker(
const simplified = ramerDouglasPeucker(
this.trkpt,
20,
getElevationDistanceFunction(statistics)
);
let slope = [];
let length = [];
const slope = [];
const length = [];
for (let i = 0; i < simplified.length - 1; i++) {
let start = simplified[i].point._data.index;
let end = simplified[i + 1].point._data.index;
let dist =
const start = simplified[i].point._data.index;
const end = simplified[i + 1].point._data.index;
const dist =
statistics.local.distance.total[end] - statistics.local.distance.total[start];
let ele = (simplified[i + 1].point.ele ?? 0) - (simplified[i].point.ele ?? 0);
const ele = (simplified[i + 1].point.ele ?? 0) - (simplified[i].point.ele ?? 0);
for (let j = start; j < end + (i + 1 === simplified.length - 1 ? 1 : 0); j++) {
slope.push((0.1 * ele) / dist);
@ -1112,8 +1112,8 @@ export class TrackSegment extends GPXTreeLeaf {
startTime?: Date,
removeGaps?: boolean
) {
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
let trkpt = og.trkpt.slice();
const og = getOriginal(this); // Read as much as possible from the original object because it is faster
const trkpt = og.trkpt.slice();
if (speed !== undefined || (trkpt.length > 0 && trkpt[0].time !== undefined)) {
// Must handle timestamps (either segment has timestamps or the new points will have timestamps)
@ -1127,7 +1127,7 @@ export class TrackSegment extends GPXTreeLeaf {
}
if (points.length > 0) {
// Adapt timestamps of the new points
let last = start > 0 ? trkpt[start - 1] : undefined;
const last = start > 0 ? trkpt[start - 1] : undefined;
if (
points[0].time === undefined ||
(points.length > 1 && points[1].time === undefined)
@ -1155,7 +1155,7 @@ export class TrackSegment extends GPXTreeLeaf {
} else {
// Different points, make the new points start one second after the previous point
if (points[0].time.getTime() - last.time.getTime() > 1000) {
let artificialLast = points[0].clone();
const artificialLast = points[0].clone();
artificialLast.time = new Date(last.time.getTime() + 1000);
points = withShiftedAndCompressedTimestamps(
points,
@ -1169,7 +1169,7 @@ export class TrackSegment extends GPXTreeLeaf {
}
if (end < trkpt.length - 1) {
// Adapt timestamps of points after [start, end]
let last =
const last =
points.length > 0
? points[points.length - 1]
: start > 0
@ -1198,9 +1198,9 @@ export class TrackSegment extends GPXTreeLeaf {
}
_reverse(originalNextTimestamp?: Date, newPreviousTimestamp?: Date) {
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
let originalStartTimestamp = og.getStartTimestamp();
let originalEndTimestamp = og.getEndTimestamp();
const og = getOriginal(this); // Read as much as possible from the original object because it is faster
const originalStartTimestamp = og.getStartTimestamp();
const originalEndTimestamp = og.getEndTimestamp();
if (!newPreviousTimestamp) {
newPreviousTimestamp = originalStartTimestamp;
}
@ -1216,13 +1216,13 @@ export class TrackSegment extends GPXTreeLeaf {
newPreviousTimestamp !== undefined &&
originalEndTimestamp !== undefined
) {
let newStartTimestamp = new Date(
const newStartTimestamp = new Date(
newPreviousTimestamp.getTime() +
originalNextTimestamp.getTime() -
originalEndTimestamp.getTime()
);
let trkpt = og.trkpt.map(
const trkpt = og.trkpt.map(
(point, i) =>
new TrackPoint({
attributes: cloneJSON(point.attributes),
@ -1245,8 +1245,8 @@ export class TrackSegment extends GPXTreeLeaf {
}
roundTrip() {
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
let newSegment = og.clone();
const og = getOriginal(this); // Read as much as possible from the original object because it is faster
const newSegment = og.clone();
newSegment._reverse(newSegment.getEndTimestamp(), newSegment.getEndTimestamp());
this.replaceTrackPoints(this.trkpt.length, this.trkpt.length, newSegment.trkpt);
}
@ -1256,9 +1256,9 @@ export class TrackSegment extends GPXTreeLeaf {
}
clean(bounds: [Coordinates, Coordinates], inside: boolean) {
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
let trkpt = og.trkpt.filter((point) => {
let inBounds =
const og = getOriginal(this); // Read as much as possible from the original object because it is faster
const trkpt = og.trkpt.filter((point) => {
const inBounds =
point.attributes.lat >= bounds[0].lat &&
point.attributes.lat <= bounds[1].lat &&
point.attributes.lon >= bounds[0].lon &&
@ -1274,12 +1274,12 @@ export class TrackSegment extends GPXTreeLeaf {
lastPoint.time = startTime;
}
let og = getOriginal(this); // Read as much as possible from the original object because it is faster
const og = getOriginal(this); // Read as much as possible from the original object because it is faster
if (og.trkpt.length > 0 && og.trkpt[0].time === undefined) {
let trkpt = withTimestamps(og.trkpt, speed, lastPoint, startTime);
const trkpt = withTimestamps(og.trkpt, speed, lastPoint, startTime);
this.trkpt = freeze(trkpt); // Pre-freeze the array, faster as well
} else {
let trkpt = withShiftedAndCompressedTimestamps(og.trkpt, speed, ratio, lastPoint);
const trkpt = withShiftedAndCompressedTimestamps(og.trkpt, speed, ratio, lastPoint);
this.trkpt = freeze(trkpt); // Pre-freeze the array, faster as well
}
}
@ -1289,9 +1289,9 @@ export class TrackSegment extends GPXTreeLeaf {
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);
const og = getOriginal(this); // Read as much as possible from the original object because it is faster
const slope = og._computeSlope();
const trkpt = withArtificialTimestamps(og.trkpt, totalTime, lastPoint, startTime, slope);
this.trkpt = freeze(trkpt); // Pre-freeze the array, faster as well
}
@ -1854,7 +1854,7 @@ export class GPXStatistics {
end = this.local.points.length - 1;
}
let statistics = new GPXStatistics();
const statistics = new GPXStatistics();
statistics.local.points = this.local.points.slice(start, end + 1);
@ -1926,14 +1926,14 @@ export function getElevationDistanceFunction(statistics: GPXStatistics) {
if (point1.ele === undefined || point2.ele === undefined || point3.ele === undefined) {
return 0;
}
let x1 = statistics.local.distance.total[point1._data.index] * 1000;
let x2 = statistics.local.distance.total[point2._data.index] * 1000;
let x3 = statistics.local.distance.total[point3._data.index] * 1000;
let y1 = point1.ele;
let y2 = point2.ele;
let y3 = point3.ele;
const x1 = statistics.local.distance.total[point1._data.index] * 1000;
const x2 = statistics.local.distance.total[point2._data.index] * 1000;
const x3 = statistics.local.distance.total[point3._data.index] * 1000;
const y1 = point1.ele;
const y2 = point2.ele;
const y3 = point3.ele;
let dist = Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2));
const dist = Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2));
if (dist === 0) {
return Math.sqrt(Math.pow(x3 - x1, 2) + Math.pow(y3 - y1, 2));
}
@ -1949,12 +1949,12 @@ function distanceWindowSmoothing(
compute: (accumulated: number, start: number, end: number) => number,
remove?: (index: number) => number
): number[] {
let result = [];
const result = [];
let start = 0,
end = 0,
accumulated = 0;
for (var i = 0; i < points.length; i++) {
for (let i = 0; i < points.length; i++) {
while (
start + 1 < i &&
distance(points[start].getCoordinates(), points[i].getCoordinates()) > distanceWindow
@ -2010,7 +2010,7 @@ function withTimestamps(
last.time = startTime;
}
return points.map((point) => {
let time = getTimestamp(last, point, speed);
const time = getTimestamp(last, point, speed);
last = point.clone();
last.time = time;
return last;
@ -2023,10 +2023,10 @@ function withShiftedAndCompressedTimestamps(
ratio: number,
lastPoint: TrackPoint
): TrackPoint[] {
let start = getTimestamp(lastPoint, points[0], speed);
const start = getTimestamp(lastPoint, points[0], speed);
let last = points[0];
return points.map((point) => {
let pt = point.clone();
const pt = point.clone();
if (point.time === undefined) {
pt.time = getTimestamp(last, point, speed);
} else {
@ -2046,19 +2046,19 @@ function withArtificialTimestamps(
startTime: Date,
slope: number[]
): TrackPoint[] {
let weight = [];
const 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])));
const dist = distance(points[i].getCoordinates(), points[i + 1].getCoordinates());
const 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();
const pt = point.clone();
if (i === 0) {
pt.time = lastPoint?.time ?? startTime;
} else {
@ -2077,7 +2077,7 @@ function getTimestamp(a: TrackPoint, b: TrackPoint, speed: number): Date {
} else if (speed === undefined) {
return new Date(a.time.getTime() + 1000);
}
let dist = distance(a.getCoordinates(), b.getCoordinates()) / 1000;
const dist = distance(a.getCoordinates(), b.getCoordinates()) / 1000;
return new Date(a.time.getTime() + (1000 * 3600 * dist) / speed);
}

View file

@ -20,7 +20,7 @@ export function ramerDouglasPeucker(
];
}
let simplified = [
const simplified = [
{
point: points[0],
},
@ -40,13 +40,13 @@ function ramerDouglasPeuckerRecursive(
end: number,
simplified: SimplifiedTrackPoint[]
) {
let largest = {
const largest = {
index: 0,
distance: 0,
};
for (let i = start + 1; i < end; i++) {
let distance = measure(points[start], points[end], points[i]);
const distance = measure(points[start], points[end], points[i]);
if (distance > largest.distance) {
largest.index = i;
largest.distance = distance;
@ -89,7 +89,7 @@ function crossarc(coord1: Coordinates, coord2: Coordinates, coord3: Coordinates)
// Prerequisites for the formulas
const bear12 = bearing(lat1, lon1, lat2, lon2);
const bear13 = bearing(lat1, lon1, lat3, lon3);
let dis13 = distance(lat1, lon1, lat3, lon3);
const dis13 = distance(lat1, lon1, lat3, lon3);
let diff = Math.abs(bear13 - bear12);
if (diff > Math.PI) {
@ -102,11 +102,11 @@ function crossarc(coord1: Coordinates, coord2: Coordinates, coord3: Coordinates)
}
// Find the cross-track distance.
let dxt = Math.asin(Math.sin(dis13 / earthRadius) * Math.sin(bear13 - bear12)) * earthRadius;
const dxt = Math.asin(Math.sin(dis13 / earthRadius) * Math.sin(bear13 - bear12)) * earthRadius;
// Is p4 beyond the arc?
let dis12 = distance(lat1, lon1, lat2, lon2);
let dis14 =
const dis12 = distance(lat1, lon1, lat2, lon2);
const dis14 =
Math.acos(Math.cos(dis13 / earthRadius) / Math.cos(dxt / earthRadius)) * earthRadius;
if (dis14 > dis12) {
return distance(lat2, lon2, lat3, lon3);
@ -162,7 +162,7 @@ function projected(coord1: Coordinates, coord2: Coordinates, coord3: Coordinates
// Prerequisites for the formulas
const bear12 = bearing(lat1, lon1, lat2, lon2);
const bear13 = bearing(lat1, lon1, lat3, lon3);
let dis13 = distance(lat1, lon1, lat3, lon3);
const dis13 = distance(lat1, lon1, lat3, lon3);
let diff = Math.abs(bear13 - bear12);
if (diff > Math.PI) {
@ -175,11 +175,11 @@ function projected(coord1: Coordinates, coord2: Coordinates, coord3: Coordinates
}
// Find the cross-track distance.
let dxt = Math.asin(Math.sin(dis13 / earthRadius) * Math.sin(bear13 - bear12)) * earthRadius;
const dxt = Math.asin(Math.sin(dis13 / earthRadius) * Math.sin(bear13 - bear12)) * earthRadius;
// Is p4 beyond the arc?
let dis12 = distance(lat1, lon1, lat2, lon2);
let dis14 =
const dis12 = distance(lat1, lon1, lat2, lon2);
const dis14 =
Math.acos(Math.cos(dis13 / earthRadius) / Math.cos(dxt / earthRadius)) * earthRadius;
if (dis14 > dis12) {
return coord2;

View file

@ -96,10 +96,10 @@ function createPattern(
size: number = 16,
lineWidth: number = 4
) {
let canvas = document.createElement('canvas');
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
let ctx = canvas.getContext('2d');
const ctx = canvas.getContext('2d');
if (ctx) {
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, size, size);
@ -139,11 +139,11 @@ export function getHighwayColor(
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;
const backgroundColor = highwayColors[highway] ? highwayColors[highway] : highwayColors.missing;
const sacScaleColor = sacScale ? sacScaleColors[sacScale] : undefined;
const mtbScaleColor = mtbScale ? mtbScaleColors[mtbScale] : undefined;
if (sacScale || mtbScale) {
let patternId = `${backgroundColor}-${[sacScale, mtbScale].filter((x) => x).join('-')}`;
const patternId = `${backgroundColor}-${[sacScale, mtbScale].filter((x) => x).join('-')}`;
if (!patterns[patternId]) {
patterns[patternId] = createPattern(backgroundColor, sacScaleColor, mtbScaleColor);
}
@ -164,8 +164,8 @@ export function getSlopeColor(slope: number): string {
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;
const hue = ((0.5 - v) * 120).toString(10);
const lightness = 90 - Math.abs(v) * 70;
return `hsl(${hue},70%,${lightness}%)`;
}

View file

@ -69,7 +69,7 @@ export type Symbol = {
iconSvg?: string;
};
export const symbols: { [key: string]: Symbol } = {
export const symbols: { [key: string]: symbol } = {
alert: { value: 'Alert', icon: TriangleAlert, iconSvg: TriangleAlertSvg },
anchor: { value: 'Anchor', icon: Anchor, iconSvg: AnchorSvg },
bank: { value: 'Bank', icon: Landmark, iconSvg: LandmarkSvg },

View file

@ -20,7 +20,7 @@ export class MapPopup {
this.map = map;
this.popup = new mapboxgl.Popup(options);
let component = new MapPopupComponent({
const component = new MapPopupComponent({
target: document.body,
props: {
item: this.item,

View file

@ -62,15 +62,15 @@ export const guideIcons: Record<string, string | ComponentType<Icon>> = {
};
export function getPreviousGuide(currentGuide: string): string | undefined {
let subguides = currentGuide.split('/');
const subguides = currentGuide.split('/');
if (subguides.length === 1) {
let keys = Object.keys(guides);
let index = keys.indexOf(currentGuide);
const keys = Object.keys(guides);
const index = keys.indexOf(currentGuide);
if (index === 0) {
return undefined;
}
let previousGuide = keys[index - 1];
const previousGuide = keys[index - 1];
if (previousGuide === undefined) {
return undefined;
} else if (guides[previousGuide].length === 0) {
@ -80,7 +80,7 @@ export function getPreviousGuide(currentGuide: string): string | undefined {
}
} else {
if (guides.hasOwnProperty(subguides[0])) {
let subguideIndex = guides[subguides[0]].indexOf(subguides[1]);
const subguideIndex = guides[subguides[0]].indexOf(subguides[1]);
if (subguideIndex > 0) {
return `${subguides[0]}/${guides[subguides[0]][subguideIndex - 1]}`;
} else {
@ -93,13 +93,13 @@ export function getPreviousGuide(currentGuide: string): string | undefined {
}
export function getNextGuide(currentGuide: string): string | undefined {
let subguides = currentGuide.split('/');
const subguides = currentGuide.split('/');
if (subguides.length === 1) {
if (guides.hasOwnProperty(currentGuide)) {
if (guides[currentGuide].length === 0) {
let keys = Object.keys(guides);
let index = keys.indexOf(currentGuide);
const keys = Object.keys(guides);
const index = keys.indexOf(currentGuide);
return keys[index + 1];
} else {
return `${currentGuide}/${guides[currentGuide][0]}`;
@ -109,12 +109,12 @@ export function getNextGuide(currentGuide: string): string | undefined {
}
} else {
if (guides.hasOwnProperty(subguides[0])) {
let subguideIndex = guides[subguides[0]].indexOf(subguides[1]);
const subguideIndex = guides[subguides[0]].indexOf(subguides[1]);
if (subguideIndex < guides[subguides[0]].length - 1) {
return `${subguides[0]}/${guides[subguides[0]][subguideIndex + 1]}`;
} else {
let keys = Object.keys(guides);
let index = keys.indexOf(subguides[0]);
const keys = Object.keys(guides);
const index = keys.indexOf(subguides[0]);
return keys[index + 1];
}
} else {

View file

@ -110,13 +110,13 @@ export function getURLForGoogleDriveFile(fileId: string): string {
}
export function convertOldEmbeddingOptions(options: URLSearchParams): any {
let newOptions: any = {
const newOptions: any = {
token: PUBLIC_MAPBOX_TOKEN,
files: [],
ids: [],
};
if (options.has('state')) {
let state = JSON.parse(options.get('state')!);
const state = JSON.parse(options.get('state')!);
if (state.ids) {
newOptions.ids.push(...state.ids);
}
@ -125,7 +125,7 @@ export function convertOldEmbeddingOptions(options: URLSearchParams): any {
}
}
if (options.has('source')) {
let basemap = options.get('source')!;
const basemap = options.get('source')!;
if (basemap === 'satellite') {
newOptions.basemap = 'mapboxSatellite';
} else if (basemap === 'otm') {

View file

@ -336,9 +336,9 @@ export function moveItems(
sortItems(fromItems, false);
sortItems(toItems, false);
let context: (GPXFile | Track | TrackSegment | Waypoint[] | Waypoint)[] = [];
const context: (GPXFile | Track | TrackSegment | Waypoint[] | Waypoint)[] = [];
fromItems.forEach((item) => {
let file = getFile(item.getFileId());
const file = getFile(item.getFileId());
if (file) {
if (item instanceof ListFileItem) {
context.push(file.clone());
@ -443,14 +443,14 @@ export function moveItems(
toItems.forEach((item, i) => {
if (item instanceof ListFileItem) {
if (context[i] instanceof GPXFile) {
let newFile = context[i];
const newFile = context[i];
if (remove) {
files.delete(newFile._data.id);
}
newFile._data.id = item.getFileId();
files.set(item.getFileId(), freeze(newFile));
} else if (context[i] instanceof Track) {
let newFile = newGPXFile();
const newFile = newGPXFile();
newFile._data.id = item.getFileId();
if (context[i].name) {
newFile.metadata.name = context[i].name;
@ -458,7 +458,7 @@ export function moveItems(
newFile.replaceTracks(0, 0, [context[i]]);
files.set(item.getFileId(), freeze(newFile));
} else if (context[i] instanceof TrackSegment) {
let newFile = newGPXFile();
const newFile = newGPXFile();
newFile._data.id = item.getFileId();
newFile.replaceTracks(0, 0, [
new Track({

View file

@ -29,7 +29,7 @@ export class SelectionTreeType {
clear() {
this.selected = false;
for (let key in this.children) {
for (const key in this.children) {
this.children[key].clear();
}
this.size = 0;
@ -37,13 +37,13 @@ export class SelectionTreeType {
_setOrToggle(item: ListItem, value?: boolean) {
if (item.level === this.item.level) {
let newSelected = value === undefined ? !this.selected : value;
const newSelected = value === undefined ? !this.selected : value;
if (this.selected !== newSelected) {
this.selected = newSelected;
this.size += this.selected ? 1 : -1;
}
} else {
let id = item.getIdAtLevel(this.item.level);
const id = item.getIdAtLevel(this.item.level);
if (id !== undefined) {
if (!this.children.hasOwnProperty(id)) {
this.children[id] = new SelectionTreeType(this.item.extend(id));
@ -67,7 +67,7 @@ export class SelectionTreeType {
if (item.level === this.item.level) {
return this.selected;
} else {
let id = item.getIdAtLevel(this.item.level);
const id = item.getIdAtLevel(this.item.level);
if (id !== undefined) {
if (this.children.hasOwnProperty(id)) {
return this.children[id].has(item);
@ -85,7 +85,7 @@ export class SelectionTreeType {
) {
return this.selected;
}
let id = item.getIdAtLevel(this.item.level);
const id = item.getIdAtLevel(this.item.level);
if (id !== undefined) {
if (this.children.hasOwnProperty(id)) {
return this.children[id].hasAnyParent(item, self);
@ -102,7 +102,7 @@ export class SelectionTreeType {
) {
return this.selected;
}
let id = item.getIdAtLevel(this.item.level);
const id = item.getIdAtLevel(this.item.level);
if (id !== undefined) {
if (ignoreIds === undefined || ignoreIds.indexOf(id) === -1) {
if (this.children.hasOwnProperty(id)) {
@ -110,7 +110,7 @@ export class SelectionTreeType {
}
}
} else {
for (let key in this.children) {
for (const key in this.children) {
if (ignoreIds === undefined || ignoreIds.indexOf(key) === -1) {
if (this.children[key].hasAnyChildren(item, self, ignoreIds)) {
return true;
@ -125,7 +125,7 @@ export class SelectionTreeType {
if (this.selected) {
selection.push(this.item);
}
for (let key in this.children) {
for (const key in this.children) {
this.children[key].getSelected(selection);
}
return selection;
@ -135,7 +135,7 @@ export class SelectionTreeType {
if (this.selected) {
callback(this.item);
}
for (let key in this.children) {
for (const key in this.children) {
this.children[key].forEach(callback);
}
}
@ -190,14 +190,14 @@ export function selectAll() {
$selection.set(new ListFileItem(fileId), true);
});
} else if (item instanceof ListTrackItem) {
let file = getFile(item.getFileId());
const file = getFile(item.getFileId());
if (file) {
file.trk.forEach((_track, trackId) => {
$selection.set(new ListTrackItem(item.getFileId(), trackId), true);
});
}
} else if (item instanceof ListTrackSegmentItem) {
let file = getFile(item.getFileId());
const file = getFile(item.getFileId());
if (file) {
file.trk[item.getTrackIndex()].trkseg.forEach((_segment, segmentId) => {
$selection.set(
@ -207,7 +207,7 @@ export function selectAll() {
});
}
} else if (item instanceof ListWaypointItem) {
let file = getFile(item.getFileId());
const file = getFile(item.getFileId());
if (file) {
file.wpt.forEach((_waypoint, waypointId) => {
$selection.set(new ListWaypointItem(item.getFileId(), waypointId), true);
@ -220,7 +220,7 @@ export function selectAll() {
}
export function getOrderedSelection(reverse: boolean = false): ListItem[] {
let selected: ListItem[] = [];
const selected: ListItem[] = [];
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
selected.push(...items);
}, reverse);
@ -234,7 +234,7 @@ export function applyToOrderedItemsFromFile(
) {
get(settings.fileOrder).forEach((fileId) => {
let level: ListLevel | undefined = undefined;
let items: ListItem[] = [];
const items: ListItem[] = [];
selectedItems.forEach((item) => {
if (item.getFileId() === fileId) {
level = item.level;
@ -268,7 +268,7 @@ export const copied = writable<ListItem[] | undefined>(undefined);
export const cut = writable(false);
export function copySelection(): boolean {
let selected = get(selection).getSelected();
const selected = get(selection).getSelected();
if (selected.length > 0) {
copied.set(selected);
cut.set(false);
@ -289,7 +289,7 @@ function resetCopied() {
}
export function pasteSelection() {
let fromItems = get(copied);
const fromItems = get(copied);
if (fromItems === undefined || fromItems.length === 0) {
return;
}
@ -299,7 +299,7 @@ export function pasteSelection() {
selected = [new ListRootItem()];
}
let fromParent = fromItems[0].getParent();
const fromParent = fromItems[0].getParent();
let toParent = selected[selected.length - 1];
let startIndex: number | undefined = undefined;
@ -315,14 +315,14 @@ export function pasteSelection() {
toParent = toParent.getParent();
}
let toItems: ListItem[] = [];
const toItems: ListItem[] = [];
if (toParent.level === ListLevel.ROOT) {
let fileIds = getFileIds(fromItems.length);
const fileIds = getFileIds(fromItems.length);
fileIds.forEach((fileId) => {
toItems.push(new ListFileItem(fileId));
});
} else {
let toFile = getFile(toParent.getFileId());
const toFile = getFile(toParent.getFileId());
if (toFile) {
fromItems.forEach((item, index) => {
if (toParent instanceof ListFileItem) {
@ -345,7 +345,7 @@ export function pasteSelection() {
}
} else if (toParent instanceof ListTrackItem) {
if (item instanceof ListTrackSegmentItem) {
let toTrackIndex = toParent.getTrackIndex();
const toTrackIndex = toParent.getTrackIndex();
toItems.push(
new ListTrackSegmentItem(
toParent.getFileId(),

View file

@ -30,7 +30,7 @@ export class DistanceMarkers {
update() {
try {
if (get(distanceMarkers)) {
let distanceSource = this.map.getSource('distance-markers');
const distanceSource = this.map.getSource('distance-markers');
if (distanceSource) {
distanceSource.setData(this.getDistanceMarkersGeoJSON());
} else {
@ -88,17 +88,17 @@ export class DistanceMarkers {
}
getDistanceMarkersGeoJSON(): GeoJSON.FeatureCollection {
let statistics = get(gpxStatistics);
const statistics = get(gpxStatistics);
let features = [];
const features = [];
let currentTargetDistance = 1;
for (let i = 0; i < statistics.local.distance.total.length; i++) {
if (
statistics.local.distance.total[i] >=
currentTargetDistance * (get(distanceUnits) === 'metric' ? 1 : 1.60934)
) {
let distance = currentTargetDistance.toFixed(0);
let [level, minzoom] = stops.find(([d]) => currentTargetDistance % d === 0) ?? [
const distance = currentTargetDistance.toFixed(0);
const [level, minzoom] = stops.find(([d]) => currentTargetDistance % d === 0) ?? [
0, 0,
];
features.push({

View file

@ -39,13 +39,13 @@ const colors = [
];
const colorCount: { [key: string]: number } = {};
for (let color of colors) {
for (const color of colors) {
colorCount[color] = 0;
}
// Get the color with the least amount of uses
function getColor() {
let color = colors.reduce((a, b) => (colorCount[a] <= colorCount[b] ? a : b));
const color = colors.reduce((a, b) => (colorCount[a] <= colorCount[b] ? a : b));
colorCount[color]++;
return color;
}
@ -82,7 +82,7 @@ class KeyDown {
}
function getMarkerForSymbol(symbol: string | undefined, layerColor: string) {
let symbolSvg = symbol ? symbols[symbol]?.iconSvg : undefined;
const symbolSvg = symbol ? symbols[symbol]?.iconSvg : undefined;
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
${Square.replace('width="24"', 'width="12"')
.replace('height="24"', 'height="12"')
@ -138,7 +138,7 @@ export class GPXLayer {
this.unsubscribe.push(file.subscribe(this.updateBinded));
this.unsubscribe.push(
selection.subscribe(($selection) => {
let newSelected = $selection.hasAnyChildren(new ListFileItem(this.fileId));
const newSelected = $selection.hasAnyChildren(new ListFileItem(this.fileId));
if (this.selected || newSelected) {
this.selected = newSelected;
this.update();
@ -170,7 +170,7 @@ export class GPXLayer {
}
update() {
let file = get(this.file)?.file;
const file = get(this.file)?.file;
if (!file) {
return;
}
@ -185,7 +185,7 @@ export class GPXLayer {
}
try {
let source = this.map.getSource(this.fileId);
const source = this.map.getSource(this.fileId);
if (source) {
source.setData(this.getGeoJSON());
} else {
@ -251,7 +251,7 @@ export class GPXLayer {
}
}
let visibleItems: [number, number][] = [];
const visibleItems: [number, number][] = [];
file.forEachSegment((segment, trackIndex, segmentIndex) => {
if (!segment._data.hidden) {
visibleItems.push([trackIndex, segmentIndex]);
@ -294,7 +294,7 @@ export class GPXLayer {
if (get(selection).hasAnyChildren(new ListFileItem(this.fileId))) {
file.wpt.forEach((waypoint) => {
// Update markers
let symbolKey = getSymbolKey(waypoint.sym);
const symbolKey = getSymbolKey(waypoint.sym);
if (markerIndex < this.markers.length) {
this.markers[markerIndex].getElement().innerHTML = getMarkerForSymbol(
symbolKey,
@ -306,10 +306,10 @@ export class GPXLayer {
writable: true,
});
} else {
let element = document.createElement('div');
const element = document.createElement('div');
element.classList.add('w-8', 'h-8', 'drop-shadow-xl');
element.innerHTML = getMarkerForSymbol(symbolKey, this.layerColor);
let marker = new mapboxgl.Marker({
const marker = new mapboxgl.Marker({
draggable: this.draggable,
element,
anchor: 'bottom',
@ -367,8 +367,8 @@ export class GPXLayer {
marker.getElement().style.cursor = '';
getElevation([marker._waypoint]).then((ele) => {
dbUtils.applyToFile(this.fileId, (file) => {
let latLng = marker.getLngLat();
let wpt = file.wpt[marker._waypoint._data.index];
const latLng = marker.getLngLat();
const wpt = file.wpt[marker._waypoint._data.index];
wpt.setCoordinates({
lat: latLng.lat,
lon: latLng.lng,
@ -446,8 +446,8 @@ export class GPXLayer {
}
layerOnMouseEnter(e: any) {
let trackIndex = e.features[0].properties.trackIndex;
let segmentIndex = e.features[0].properties.segmentIndex;
const trackIndex = e.features[0].properties.trackIndex;
const segmentIndex = e.features[0].properties.segmentIndex;
if (
get(currentTool) === Tool.SCISSORS &&
@ -467,8 +467,8 @@ export class GPXLayer {
layerOnMouseMove(e: any) {
if (inspectKeyDown?.isDown()) {
let trackIndex = e.features[0].properties.trackIndex;
let segmentIndex = e.features[0].properties.segmentIndex;
const trackIndex = e.features[0].properties.trackIndex;
const segmentIndex = e.features[0].properties.segmentIndex;
const file = get(this.file)?.file;
if (file) {
@ -489,8 +489,8 @@ export class GPXLayer {
return;
}
let trackIndex = e.features[0].properties.trackIndex;
let segmentIndex = e.features[0].properties.segmentIndex;
const trackIndex = e.features[0].properties.trackIndex;
const segmentIndex = e.features[0].properties.segmentIndex;
if (
get(currentTool) === Tool.SCISSORS &&
@ -505,7 +505,7 @@ export class GPXLayer {
return;
}
let file = get(this.file)?.file;
const file = get(this.file)?.file;
if (!file) {
return;
}
@ -535,7 +535,7 @@ export class GPXLayer {
}
getGeoJSON(): GeoJSON.FeatureCollection {
let file = get(this.file)?.file;
const file = get(this.file)?.file;
if (!file) {
return {
type: 'FeatureCollection',
@ -543,11 +543,11 @@ export class GPXLayer {
};
}
let data = file.toGeoJSON();
const data = file.toGeoJSON();
let trackIndex = 0,
segmentIndex = 0;
for (let feature of data.features) {
for (const feature of data.features) {
if (!feature.properties) {
feature.properties = {};
}

View file

@ -12,8 +12,8 @@ export class StartEndMarkers {
constructor(map: mapboxgl.Map) {
this.map = map;
let startElement = document.createElement('div');
let endElement = document.createElement('div');
const startElement = document.createElement('div');
const endElement = document.createElement('div');
startElement.className = `h-4 w-4 rounded-full bg-green-500 border-2 border-white`;
endElement.className = `h-4 w-4 rounded-full border-2 border-white`;
endElement.style.background =
@ -28,8 +28,8 @@ export class StartEndMarkers {
}
update() {
let tool = get(currentTool);
let statistics = get(slicedGPXStatistics)?.[0] ?? get(gpxStatistics);
const tool = get(currentTool);
const statistics = get(slicedGPXStatistics)?.[0] ?? get(gpxStatistics);
if (statistics.local.points.length > 0 && tool !== Tool.ROUTING) {
this.start.setLngLat(statistics.local.points[0].getCoordinates()).addTo(this.map);
this.end

View file

@ -12,7 +12,7 @@ const mercator = new SphericalMercator({
size: 256,
});
let data = writable<GeoJSON.FeatureCollection>({ type: 'FeatureCollection', features: [] });
const data = writable<GeoJSON.FeatureCollection>({ type: 'FeatureCollection', features: [] });
liveQuery(() => db.overpassdata.toArray()).subscribe((pois) => {
data.set({ type: 'FeatureCollection', features: pois.map((poi) => poi.poi) });
@ -68,10 +68,10 @@ export class OverpassLayer {
update() {
this.loadIcons();
let d = get(data);
const d = get(data);
try {
let source = this.map.getSource('overpass');
const source = this.map.getSource('overpass');
if (source) {
source.setData(d);
} else {
@ -132,13 +132,13 @@ export class OverpassLayer {
}
query(bbox: [number, number, number, number]) {
let queries = getCurrentQueries();
const queries = getCurrentQueries();
if (queries.length === 0) {
return;
}
let tileLimits = mercator.xyz(bbox, this.queryZoom);
let time = Date.now();
const tileLimits = mercator.xyz(bbox, this.queryZoom);
const time = Date.now();
for (let x = tileLimits.minX; x <= tileLimits.maxX; x++) {
for (let y = tileLimits.minY; y <= tileLimits.maxY; y++) {
@ -151,7 +151,7 @@ export class OverpassLayer {
.equals([x, y])
.toArray()
.then((querytiles) => {
let missingQueries = queries.filter(
const missingQueries = queries.filter(
(query) =>
!querytiles.some(
(querytile) =>
@ -191,16 +191,16 @@ export class OverpassLayer {
}
storeOverpassData(x: number, y: number, queries: string[], data: any) {
let time = Date.now();
let queryTiles = queries.map((query) => ({ x, y, query, time }));
let pois: { query: string; id: number; poi: GeoJSON.Feature }[] = [];
const time = Date.now();
const queryTiles = queries.map((query) => ({ x, y, query, time }));
const pois: { query: string; id: number; poi: GeoJSON.Feature }[] = [];
if (data.elements === undefined) {
return;
}
for (let element of data.elements) {
for (let query of queries) {
for (const element of data.elements) {
for (const query of queries) {
if (belongsToQuery(element, query)) {
pois.push({
query,
@ -236,10 +236,10 @@ export class OverpassLayer {
}
loadIcons() {
let currentQueries = getCurrentQueries();
const currentQueries = getCurrentQueries();
currentQueries.forEach((query) => {
if (!this.map.hasImage(`overpass-${query}`)) {
let icon = new Image(100, 100);
const icon = new Image(100, 100);
icon.onload = () => {
if (!this.map.hasImage(`overpass-${query}`)) {
this.map.addImage(`overpass-${query}`, icon);
@ -280,7 +280,7 @@ function getQuery(query: string) {
}
function getQueryItem(tags: Record<string, string | boolean | string[]>) {
let arrayEntry = Object.entries(tags).find(([_, value]) => Array.isArray(value));
const arrayEntry = Object.entries(tags).find(([_, value]) => Array.isArray(value));
if (arrayEntry !== undefined) {
return arrayEntry[1]
.map(
@ -312,7 +312,7 @@ function belongsToQueryItem(element: any, tags: Record<string, string | boolean
}
function getCurrentQueries() {
let currentQueries = get(currentOverpassQueries);
const currentQueries = get(currentOverpassQueries);
if (currentQueries === undefined) {
return [];
}

View file

@ -78,7 +78,7 @@ export class MapillaryLayer {
this.viewer.on('position', async () => {
if (this.active) {
popupOpen.set(true);
let latLng = await this.viewer.getPosition();
const latLng = await this.viewer.getPosition();
this.marker.setLngLat(latLng).addTo(this.map);
if (!this.map.getBounds()?.contains(latLng)) {
this.map.panTo(latLng);

View file

@ -59,20 +59,20 @@ async function getRoute(
brouterProfile: string,
privateRoads: boolean
): Promise<TrackPoint[]> {
let url = `https://routing.gpx.studio?lonlats=${points.map((point) => `${point.lon.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile + (privateRoads ? '-private' : '')}&format=geojson&alternativeidx=0`;
const url = `https://routing.gpx.studio?lonlats=${points.map((point) => `${point.lon.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile + (privateRoads ? '-private' : '')}&format=geojson&alternativeidx=0`;
let response = await fetch(url);
const response = await fetch(url);
// Check if the response is ok
if (!response.ok) {
throw new Error(`${await response.text()}`);
}
let geojson = await response.json();
const geojson = await response.json();
let route: TrackPoint[] = [];
let coordinates = geojson.features[0].geometry.coordinates;
let messages = geojson.features[0].properties.messages;
const route: TrackPoint[] = [];
const coordinates = geojson.features[0].geometry.coordinates;
const messages = geojson.features[0].properties.messages;
const lngIdx = messages[0].indexOf('Longitude');
const latIdx = messages[0].indexOf('Latitude');
@ -81,7 +81,7 @@ async function getRoute(
let tags = messageIdx < messages.length ? getTags(messages[messageIdx][tagIdx]) : {};
for (let i = 0; i < coordinates.length; i++) {
let coord = coordinates[i];
const coord = coordinates[i];
route.push(
new TrackPoint({
attributes: {
@ -111,7 +111,7 @@ async function getRoute(
function getTags(message: string): { [key: string]: string } {
const fields = message.split(' ');
let tags: { [key: string]: string } = {};
const tags: { [key: string]: string } = {};
for (let i = 0; i < fields.length; i++) {
let [key, value] = fields[i].split('=');
key = key.replace(/:/g, '_');
@ -121,15 +121,15 @@ function getTags(message: string): { [key: string]: string } {
}
function getIntermediatePoints(points: Coordinates[]): Promise<TrackPoint[]> {
let route: TrackPoint[] = [];
let step = 0.05;
const route: TrackPoint[] = [];
const step = 0.05;
for (let i = 0; i < points.length - 1; i++) {
// Add intermediate points between each pair of points
let dist = distance(points[i], points[i + 1]) / 1000;
const dist = distance(points[i], points[i + 1]) / 1000;
for (let d = 0; d < dist; d += step) {
let lat = points[i].lat + (d / dist) * (points[i + 1].lat - points[i].lat);
let lon = points[i].lon + (d / dist) * (points[i + 1].lon - points[i].lon);
const lat = points[i].lat + (d / dist) * (points[i + 1].lat - points[i].lat);
const lon = points[i].lon + (d / dist) * (points[i + 1].lon - points[i].lon);
route.push(
new TrackPoint({
attributes: {

View file

@ -54,7 +54,7 @@ export class RoutingControls {
this.popup = popup;
this.popupElement = popupElement;
let point = new TrackPoint({
const point = new TrackPoint({
attributes: {
lat: 0,
lon: 0,
@ -68,7 +68,7 @@ export class RoutingControls {
}
addIfNeeded() {
let routing = get(currentTool) === Tool.ROUTING;
const routing = get(currentTool) === Tool.ROUTING;
if (!routing) {
if (this.active) {
this.remove();
@ -76,7 +76,7 @@ export class RoutingControls {
return;
}
let selected = get(selection).hasAnyChildren(new ListFileItem(this.fileId), true, [
const selected = get(selection).hasAnyChildren(new ListFileItem(this.fileId), true, [
'waypoints',
]);
if (selected) {
@ -103,7 +103,7 @@ export class RoutingControls {
updateControls() {
// Update the markers when the file changes
let file = get(this.file)?.file;
const file = get(this.file)?.file;
if (!file) {
return;
}
@ -115,7 +115,7 @@ export class RoutingControls {
new ListTrackSegmentItem(this.fileId, trackIndex, segmentIndex)
)
) {
for (let point of segment.trkpt) {
for (const point of segment.trkpt) {
// Update the existing anchors (could be improved by matching the existing anchors with the new ones?)
if (point._data.anchor) {
if (anchorIndex < this.anchors.length) {
@ -146,7 +146,7 @@ export class RoutingControls {
remove() {
this.active = false;
for (let anchor of this.anchors) {
for (const anchor of this.anchors) {
anchor.marker.remove();
}
this.map.off('move', this.toggleAnchorsForZoomLevelAndBoundsBinded);
@ -169,16 +169,16 @@ export class RoutingControls {
trackIndex: number,
segmentIndex: number
): AnchorWithMarker {
let element = document.createElement('div');
const element = document.createElement('div');
element.className = `h-5 w-5 xs:h-4 xs:w-4 md:h-3 md:w-3 rounded-full bg-white border-2 border-black cursor-pointer`;
let marker = new mapboxgl.Marker({
const marker = new mapboxgl.Marker({
draggable: true,
className: 'z-10',
element,
}).setLngLat(point.getCoordinates());
let anchor = {
const anchor = {
point,
segment,
trackIndex,
@ -200,7 +200,7 @@ export class RoutingControls {
element.classList.add('cursor-pointer');
this.moveAnchor(anchor);
});
let handleAnchorClick = this.handleClickForAnchor(anchor, marker);
const handleAnchorClick = this.handleClickForAnchor(anchor, marker);
marker.getElement().addEventListener('click', handleAnchorClick);
marker.getElement().addEventListener('contextmenu', handleAnchorClick);
@ -231,7 +231,7 @@ export class RoutingControls {
if (anchor.point._data.index === 0) {
return false;
}
let segment = anchor.segment;
const segment = anchor.segment;
if (
distance(
segment.trkpt[0].getCoordinates(),
@ -246,9 +246,9 @@ export class RoutingControls {
marker.setPopup(this.popup);
marker.togglePopup();
let deleteThisAnchor = this.getDeleteAnchor(anchor);
const deleteThisAnchor = this.getDeleteAnchor(anchor);
this.popupElement.addEventListener('delete', deleteThisAnchor); // Register the delete event for this anchor
let startLoopAtThisAnchor = this.getStartLoopAtAnchor(anchor);
const startLoopAtThisAnchor = this.getStartLoopAtAnchor(anchor);
this.popupElement.addEventListener('change-start', startLoopAtThisAnchor); // Register the start loop event for this anchor
this.popup.once('close', () => {
this.popupElement.removeEventListener('delete', deleteThisAnchor);
@ -261,12 +261,12 @@ export class RoutingControls {
// Show markers only if they are in the current zoom level and bounds
this.shownAnchors.splice(0, this.shownAnchors.length);
let center = this.map.getCenter();
let bottomLeft = this.map.unproject([0, this.map.getCanvas().height]);
let topRight = this.map.unproject([this.map.getCanvas().width, 0]);
let diagonal = bottomLeft.distanceTo(topRight);
const center = this.map.getCenter();
const bottomLeft = this.map.unproject([0, this.map.getCanvas().height]);
const topRight = this.map.unproject([this.map.getCanvas().width, 0]);
const diagonal = bottomLeft.distanceTo(topRight);
let zoom = this.map.getZoom();
const zoom = this.map.getZoom();
this.anchors.forEach((anchor) => {
anchor.inZoom = anchor.point._data.zoom <= zoom;
if (anchor.inZoom && center.distanceTo(anchor.marker.getLngLat()) < diagonal) {
@ -334,7 +334,7 @@ export class RoutingControls {
}
temporaryAnchorCloseToOtherAnchor(e: any) {
for (let anchor of this.shownAnchors) {
for (const anchor of this.shownAnchors) {
if (e.point.dist(this.map.project(anchor.marker.getLngLat())) < 10) {
return true;
}
@ -344,7 +344,7 @@ export class RoutingControls {
async moveAnchor(anchorWithMarker: AnchorWithMarker) {
// Move the anchor and update the route from and to the neighbouring anchors
let coordinates = {
const coordinates = {
lat: anchorWithMarker.marker.getLngLat().lat,
lon: anchorWithMarker.marker.getLngLat().lng,
};
@ -356,10 +356,10 @@ export class RoutingControls {
anchor = this.getPermanentAnchor();
}
let [previousAnchor, nextAnchor] = this.getNeighbouringAnchors(anchor);
const [previousAnchor, nextAnchor] = this.getNeighbouringAnchors(anchor);
let anchors = [];
let targetCoordinates = [];
const anchors = [];
const targetCoordinates = [];
if (previousAnchor !== null) {
anchors.push(previousAnchor);
@ -374,7 +374,7 @@ export class RoutingControls {
targetCoordinates.push(nextAnchor.point.getCoordinates());
}
let success = await this.routeBetweenAnchors(anchors, targetCoordinates);
const success = await this.routeBetweenAnchors(anchors, targetCoordinates);
if (!success) {
// Route failed, revert the anchor to the previous position
@ -383,7 +383,7 @@ export class RoutingControls {
}
getPermanentAnchor(): Anchor {
let file = get(this.file)?.file;
const file = get(this.file)?.file;
// Find the point closest to the temporary anchor
let minDetails: any = { distance: Number.MAX_VALUE };
@ -394,8 +394,8 @@ export class RoutingControls {
new ListTrackSegmentItem(this.fileId, trackIndex, segmentIndex)
)
) {
let details: any = {};
let closest = getClosestLinePoint(
const details: any = {};
const closest = getClosestLinePoint(
segment.trkpt,
this.temporaryAnchor.point,
details
@ -425,7 +425,7 @@ export class RoutingControls {
}
turnIntoPermanentAnchor() {
let file = get(this.file)?.file;
const file = get(this.file)?.file;
// Find the point closest to the temporary anchor
let minDetails: any = { distance: Number.MAX_VALUE };
@ -442,22 +442,22 @@ export class RoutingControls {
new ListTrackSegmentItem(this.fileId, trackIndex, segmentIndex)
)
) {
let details: any = {};
const details: any = {};
getClosestLinePoint(segment.trkpt, this.temporaryAnchor.point, details);
if (details.distance < minDetails.distance) {
minDetails = details;
let before = details.before ? details.index : details.index - 1;
const before = details.before ? details.index : details.index - 1;
let projectedPt = projectedPoint(
const projectedPt = projectedPoint(
segment.trkpt[before],
segment.trkpt[before + 1],
this.temporaryAnchor.point
);
let ratio =
const ratio =
distance(segment.trkpt[before], projectedPt) /
distance(segment.trkpt[before], segment.trkpt[before + 1]);
let point = segment.trkpt[before].clone();
const point = segment.trkpt[before].clone();
point.setCoordinates(projectedPt);
point.ele =
(1 - ratio) * (segment.trkpt[before].ele ?? 0) +
@ -505,7 +505,7 @@ export class RoutingControls {
// Remove the anchor and route between the neighbouring anchors if they exist
this.popup.remove();
let [previousAnchor, nextAnchor] = this.getNeighbouringAnchors(anchor);
const [previousAnchor, nextAnchor] = this.getNeighbouringAnchors(anchor);
if (previousAnchor === null && nextAnchor === null) {
// Only one point, remove it
@ -526,7 +526,7 @@ export class RoutingControls {
} else if (nextAnchor === null) {
// Last point, remove trackpoints from previousAnchor
dbUtils.applyToFile(this.fileId, (file) => {
let segment = file.getSegment(anchor.trackIndex, anchor.segmentIndex);
const segment = file.getSegment(anchor.trackIndex, anchor.segmentIndex);
file.replaceTrackPoints(
anchor.trackIndex,
anchor.segmentIndex,
@ -551,16 +551,16 @@ export class RoutingControls {
startLoopAtAnchor(anchor: Anchor) {
this.popup.remove();
let fileWithStats = get(this.file);
const fileWithStats = get(this.file);
if (!fileWithStats) {
return;
}
let speed = fileWithStats.statistics.getStatisticsFor(
const speed = fileWithStats.statistics.getStatisticsFor(
new ListTrackSegmentItem(this.fileId, anchor.trackIndex, anchor.segmentIndex)
).global.speed.moving;
let segment = anchor.segment;
const segment = anchor.segment;
dbUtils.applyToFile(this.fileId, (file) => {
file.replaceTrackPoints(
anchor.trackIndex,
@ -593,15 +593,15 @@ export class RoutingControls {
async appendAnchorWithCoordinates(coordinates: Coordinates) {
// Add a new anchor to the end of the last segment
let selected = getOrderedSelection();
const selected = getOrderedSelection();
if (selected.length === 0 || selected[selected.length - 1].getFileId() !== this.fileId) {
return;
}
let item = selected[selected.length - 1];
const item = selected[selected.length - 1];
let lastAnchor = this.anchors[this.anchors.length - 1];
const lastAnchor = this.anchors[this.anchors.length - 1];
let newPoint = new TrackPoint({
const newPoint = new TrackPoint({
attributes: coordinates,
});
newPoint._data.anchor = true;
@ -621,11 +621,11 @@ export class RoutingControls {
segmentIndex = item.getSegmentIndex();
}
if (file.trk.length === 0) {
let track = new Track();
const track = new Track();
track.replaceTrackPoints(0, 0, 0, [newPoint]);
file.replaceTracks(0, 0, [track]);
} else if (file.trk[trackIndex].trkseg.length === 0) {
let segment = new TrackSegment();
const segment = new TrackSegment();
segment.replaceTrackPoints(0, 0, [newPoint]);
file.replaceTrackSegments(trackIndex, 0, 0, [segment]);
} else {
@ -636,7 +636,7 @@ export class RoutingControls {
}
newPoint._data.index = lastAnchor.segment.trkpt.length - 1; // Do as if the point was the last point in the segment
let newAnchor = {
const newAnchor = {
point: newPoint,
segment: lastAnchor.segment,
trackIndex: lastAnchor.trackIndex,
@ -680,9 +680,9 @@ export class RoutingControls {
anchors: Anchor[],
targetCoordinates: Coordinates[]
): Promise<boolean> {
let segment = anchors[0].segment;
const segment = anchors[0].segment;
let fileWithStats = get(this.file);
const fileWithStats = get(this.file);
if (!fileWithStats) {
return false;
}
@ -753,7 +753,7 @@ export class RoutingControls {
anchor.point._data.zoom = 0; // Make these anchors permanent
});
let stats = fileWithStats.statistics.getStatisticsFor(
const stats = fileWithStats.statistics.getStatisticsFor(
new ListTrackSegmentItem(this.fileId, anchors[0].trackIndex, anchors[0].segmentIndex)
);
let speed: number | undefined = undefined;
@ -765,14 +765,14 @@ export class RoutingControls {
replacingDistance +=
distance(response[i - 1].getCoordinates(), response[i].getCoordinates()) / 1000;
}
let replacedDistance =
const replacedDistance =
stats.local.distance.moving[anchors[anchors.length - 1].point._data.index] -
stats.local.distance.moving[anchors[0].point._data.index];
let newDistance = stats.global.distance.moving + replacingDistance - replacedDistance;
let newTime = (newDistance / stats.global.speed.moving) * 3600;
const newDistance = stats.global.distance.moving + replacingDistance - replacedDistance;
const newTime = (newDistance / stats.global.speed.moving) * 3600;
let remainingTime =
const remainingTime =
stats.global.time.moving -
(stats.local.time.moving[anchors[anchors.length - 1].point._data.index] -
stats.local.time.moving[anchors[0].point._data.index]);
@ -789,7 +789,7 @@ export class RoutingControls {
if (startTime === undefined) {
// Replacing the first point
let endIndex = anchors[anchors.length - 1].point._data.index;
const endIndex = anchors[anchors.length - 1].point._data.index;
startTime = new Date(
(segment.trkpt[endIndex].time?.getTime() ?? 0) -
(replacingTime +

View file

@ -14,9 +14,9 @@ export function getZoomLevelForDistance(latitude: number, distance?: number): nu
}
export function updateAnchorPoints(file: GPXFile) {
let segments = file.getSegments();
const segments = file.getSegments();
for (let segment of segments) {
for (const segment of segments) {
if (!segment._data.anchors) {
// New segment, compute anchor points for it
computeAnchorPoints(segment);
@ -34,10 +34,10 @@ export function updateAnchorPoints(file: GPXFile) {
}
function computeAnchorPoints(segment: TrackSegment) {
let points = segment.trkpt;
let anchors = ramerDouglasPeucker(points, 1);
const points = segment.trkpt;
const anchors = ramerDouglasPeucker(points, 1);
anchors.forEach((anchor) => {
let point = anchor.point;
const point = anchor.point;
point._data.anchor = true;
point._data.zoom = getZoomLevelForDistance(point.getLatitude(), anchor.distance);
});

View file

@ -30,7 +30,7 @@ export class SplitControls {
}
addIfNeeded() {
let scissors = get(currentTool) === Tool.SCISSORS;
const scissors = get(currentTool) === Tool.SCISSORS;
if (!scissors) {
if (this.active) {
this.remove();
@ -56,7 +56,7 @@ export class SplitControls {
// Update the markers when the files change
let controlIndex = 0;
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = getFile(fileId);
const file = getFile(fileId);
if (file) {
file.forEachSegment((segment, trackIndex, segmentIndex) => {
@ -65,7 +65,7 @@ export class SplitControls {
new ListTrackSegmentItem(fileId, trackIndex, segmentIndex)
)
) {
for (let point of segment.trkpt.slice(1, -1)) {
for (const point of segment.trkpt.slice(1, -1)) {
// Update the existing controls (could be improved by matching the existing controls with the new ones?)
if (point._data.anchor) {
if (controlIndex < this.controls.length) {
@ -107,7 +107,7 @@ export class SplitControls {
remove() {
this.active = false;
for (let control of this.controls) {
for (const control of this.controls) {
control.marker.remove();
}
this.map.off('zoom', this.toggleControlsForZoomLevelAndBoundsBinded);
@ -118,11 +118,11 @@ export class SplitControls {
// Show markers only if they are in the current zoom level and bounds
this.shownControls.splice(0, this.shownControls.length);
let southWest = this.map.unproject([0, this.map.getCanvas().height]);
let northEast = this.map.unproject([this.map.getCanvas().width, 0]);
let bounds = new mapboxgl.LngLatBounds(southWest, northEast);
const southWest = this.map.unproject([0, this.map.getCanvas().height]);
const northEast = this.map.unproject([this.map.getCanvas().width, 0]);
const bounds = new mapboxgl.LngLatBounds(southWest, northEast);
let zoom = this.map.getZoom();
const zoom = this.map.getZoom();
this.controls.forEach((control) => {
control.inZoom = control.point._data.zoom <= zoom;
if (control.inZoom && bounds.contains(control.marker.getLngLat())) {
@ -141,19 +141,19 @@ export class SplitControls {
trackIndex: number,
segmentIndex: number
): ControlWithMarker {
let element = document.createElement('div');
const element = document.createElement('div');
element.className = `h-6 w-6 p-0.5 rounded-full bg-white border-2 border-black cursor-pointer`;
element.innerHTML = Scissors.replace('width="24"', '')
.replace('height="24"', '')
.replace('stroke="currentColor"', 'stroke="black"');
let marker = new mapboxgl.Marker({
const marker = new mapboxgl.Marker({
draggable: true,
className: 'z-10',
element,
}).setLngLat(point.getCoordinates());
let control = {
const control = {
point,
segment,
fileId,

View file

@ -100,7 +100,7 @@ export function bidirectionalDexieStore<K, V>(
initialize: boolean = true
): Writable<V | undefined> {
let first = true;
let store = writable<V | undefined>(initialize ? initial : undefined);
const store = writable<V | undefined>(initialize ? initial : undefined);
liveQuery(() => table.get(key)).subscribe((value) => {
if (value === undefined) {
if (first) {
@ -123,7 +123,7 @@ export function bidirectionalDexieStore<K, V>(
}
},
update: (callback: (value: any) => any) => {
let newValue = callback(get(store));
const newValue = callback(get(store));
if (typeof newValue === 'object' || newValue !== get(store)) {
table.put(newValue, key);
}
@ -179,7 +179,7 @@ export const settings = {
// Wrap Dexie live queries in a Svelte store to avoid triggering the query for every subscriber
function dexieStore<T>(querier: () => T | Promise<T>, initial?: T): Readable<T> {
let store = writable<T>(initial);
const store = writable<T>(initial);
liveQuery(querier).subscribe((value) => {
if (value !== undefined) {
store.set(value);
@ -211,8 +211,8 @@ export class GPXStatisticsTree {
}
getStatisticsFor(item: ListItem): GPXStatistics {
let statistics = new GPXStatistics();
let id = item.getIdAtLevel(this.level);
const statistics = new GPXStatistics();
const id = item.getIdAtLevel(this.level);
if (id === undefined || id === 'waypoints') {
Object.keys(this.statistics).forEach((key) => {
if (this.statistics[key] instanceof GPXStatistics) {
@ -222,7 +222,7 @@ export class GPXStatisticsTree {
}
});
} else {
let child = this.statistics[id];
const child = this.statistics[id];
if (child instanceof GPXStatistics) {
statistics.mergeWith(child);
} else if (child !== undefined) {
@ -236,13 +236,13 @@ export type GPXFileWithStatistics = { file: GPXFile; statistics: GPXStatisticsTr
// Wrap Dexie live queries in a Svelte store to avoid triggering the query for every subscriber, also takes care of the conversion to a GPXFile object
function dexieGPXFileStore(id: string): Readable<GPXFileWithStatistics> & { destroy: () => void } {
let store = writable<GPXFileWithStatistics>(undefined);
let query = liveQuery(() => db.files.get(id)).subscribe((value) => {
const store = writable<GPXFileWithStatistics>(undefined);
const query = liveQuery(() => db.files.get(id)).subscribe((value) => {
if (value !== undefined) {
let gpx = new GPXFile(value);
const gpx = new GPXFile(value);
updateAnchorPoints(gpx);
let statistics = new GPXStatisticsTree(gpx);
const statistics = new GPXStatisticsTree(gpx);
if (!fileState.has(id)) {
// Update the map bounds for new files
updateTargetMapBounds(
@ -272,27 +272,27 @@ function dexieGPXFileStore(id: string): Readable<GPXFileWithStatistics> & { dest
}
function updateSelection(updatedFiles: GPXFile[], deletedFileIds: string[]) {
let removedItems: ListItem[] = [];
const removedItems: ListItem[] = [];
applyToOrderedItemsFromFile(get(selection).getSelected(), (fileId, level, items) => {
let file = updatedFiles.find((file) => file._data.id === fileId);
const file = updatedFiles.find((file) => file._data.id === fileId);
if (file) {
items.forEach((item) => {
if (item instanceof ListTrackItem) {
let newTrackIndex = file.trk.findIndex(
const newTrackIndex = file.trk.findIndex(
(track) => track._data.trackIndex === item.getTrackIndex()
);
if (newTrackIndex === -1) {
removedItems.push(item);
}
} else if (item instanceof ListTrackSegmentItem) {
let newTrackIndex = file.trk.findIndex(
const newTrackIndex = file.trk.findIndex(
(track) => track._data.trackIndex === item.getTrackIndex()
);
if (newTrackIndex === -1) {
removedItems.push(item);
} else {
let newSegmentIndex = file.trk[newTrackIndex].trkseg.findIndex(
const newSegmentIndex = file.trk[newTrackIndex].trkseg.findIndex(
(segment) => segment._data.segmentIndex === item.getSegmentIndex()
);
if (newSegmentIndex === -1) {
@ -300,7 +300,7 @@ function updateSelection(updatedFiles: GPXFile[], deletedFileIds: string[]) {
}
}
} else if (item instanceof ListWaypointItem) {
let newWaypointIndex = file.wpt.findIndex(
const newWaypointIndex = file.wpt.findIndex(
(wpt) => wpt._data.index === item.getWaypointIndex()
);
if (newWaypointIndex === -1) {
@ -331,7 +331,7 @@ function updateSelection(updatedFiles: GPXFile[], deletedFileIds: string[]) {
// Commit the changes to the file state to the database
function commitFileStateChange(newFileState: ReadonlyMap<string, GPXFile>, patch: Patch[]) {
let changedFileIds = getChangedFileIds(patch);
const changedFileIds = getChangedFileIds(patch);
let updatedFileIds: string[] = [],
deletedFileIds: string[] = [];
@ -343,7 +343,7 @@ function commitFileStateChange(newFileState: ReadonlyMap<string, GPXFile>, patch
}
});
let updatedFiles = updatedFileIds
const updatedFiles = updatedFileIds
.map((id) => newFileState.get(id))
.filter((file) => file !== undefined) as GPXFile[];
updatedFileIds = updatedFiles.map((file) => file._data.id);
@ -378,11 +378,11 @@ export function observeFilesFromDatabase(fitBounds: boolean) {
initialize = false;
}
// Find new files to observe
let newFiles = dbFileIds
const newFiles = dbFileIds
.filter((id) => !get(fileObservers).has(id))
.sort((a, b) => parseInt(a.split('-')[1]) - parseInt(b.split('-')[1]));
// Find deleted files to stop observing
let deletedFiles = Array.from(get(fileObservers).keys()).filter(
const deletedFiles = Array.from(get(fileObservers).keys()).filter(
(id) => !dbFileIds.find((fileId) => fileId === id)
);
@ -405,7 +405,7 @@ export function observeFilesFromDatabase(fitBounds: boolean) {
}
});
deletedFiles.forEach((fileId) => {
let index = order.indexOf(fileId);
const index = order.indexOf(fileId);
if (index !== -1) {
order.splice(index, 1);
}
@ -417,12 +417,12 @@ export function observeFilesFromDatabase(fitBounds: boolean) {
}
export function getFile(fileId: string): GPXFile | undefined {
let fileStore = get(fileObservers).get(fileId);
const fileStore = get(fileObservers).get(fileId);
return fileStore ? get(fileStore)?.file : undefined;
}
export function getStatistics(fileId: string): GPXStatisticsTree | undefined {
let fileStore = get(fileObservers).get(fileId);
const fileStore = get(fileObservers).get(fileId);
return fileStore ? get(fileStore)?.statistics : undefined;
}
@ -463,7 +463,7 @@ function applyGlobal(callback: (files: Map<string, GPXFile>) => void) {
function applyToFiles(fileIds: string[], callback: (file: WritableDraft<GPXFile>) => void) {
const [newFileState, patch, inversePatch] = produceWithPatches(fileState, (draft) => {
fileIds.forEach((fileId) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
callback(file);
}
@ -484,7 +484,7 @@ function applyEachToFilesAndGlobal(
) {
const [newFileState, patch, inversePatch] = produceWithPatches(fileState, (draft) => {
fileIds.forEach((fileId, index) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
callbacks[index](file, context);
}
@ -502,7 +502,7 @@ const MAX_PATCHES = 100;
async function storePatches(patch: Patch[], inversePatch: Patch[]) {
if (get(patchIndex) !== undefined) {
db.patches.where(':id').above(get(patchIndex)).delete(); // Delete all patches after the current patch to avoid redoing them
let minmax = get(patchMinMaxIndex);
const minmax = get(patchMinMaxIndex);
if (minmax.max - minmax.min + 1 > MAX_PATCHES) {
db.patches
.where(':id')
@ -511,7 +511,7 @@ async function storePatches(patch: Patch[], inversePatch: Patch[]) {
}
}
db.transaction('rw', db.patches, db.settings, async () => {
let index = get(patchIndex) + 1;
const index = get(patchIndex) + 1;
await db.patches.put(
{
patch,
@ -526,14 +526,14 @@ async function storePatches(patch: Patch[], inversePatch: Patch[]) {
// Apply a patch to the file state
function applyPatch(patch: Patch[]) {
let newFileState = applyPatches(fileState, patch);
const newFileState = applyPatches(fileState, patch);
return commitFileStateChange(newFileState, patch);
}
// Get the file ids of the files that have changed in the patch
function getChangedFileIds(patch: Patch[]): string[] {
let changedFileIds = new Set<string>();
for (let p of patch) {
const changedFileIds = new Set<string>();
for (const p of patch) {
changedFileIds.add(p.path[0]);
}
return Array.from(changedFileIds);
@ -541,9 +541,9 @@ function getChangedFileIds(patch: Patch[]): string[] {
// Generate unique file ids, different from the ones in the database
export function getFileIds(n: number) {
let ids = [];
const ids = [];
for (let index = 0; ids.length < n; index++) {
let id = `gpx-${index}`;
const id = `gpx-${index}`;
if (!get(fileObservers).has(id)) {
ids.push(id);
}
@ -562,7 +562,7 @@ export const dbUtils = {
});
},
addMultiple: (files: GPXFile[]) => {
let ids = getFileIds(files.length);
const ids = getFileIds(files.length);
applyGlobal((draft) => {
files.forEach((file, index) => {
file._data.id = ids[index];
@ -590,30 +590,30 @@ export const dbUtils = {
return;
}
applyGlobal((draft) => {
let ids = getFileIds(get(settings.fileOrder).length);
const ids = getFileIds(get(settings.fileOrder).length);
let index = 0;
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
if (level === ListLevel.FILE) {
let file = getFile(fileId);
const file = getFile(fileId);
if (file) {
let newFile = file.clone();
const newFile = file.clone();
newFile._data.id = ids[index++];
draft.set(newFile._data.id, freeze(newFile));
}
} else {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
if (level === ListLevel.TRACK) {
for (let item of items) {
let trackIndex = (item as ListTrackItem).getTrackIndex();
for (const item of items) {
const trackIndex = (item as ListTrackItem).getTrackIndex();
file.replaceTracks(trackIndex + 1, trackIndex, [
file.trk[trackIndex].clone(),
]);
}
} else if (level === ListLevel.SEGMENT) {
for (let item of items) {
let trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
for (const item of items) {
const trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
const segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
file.replaceTrackSegments(
trackIndex,
segmentIndex + 1,
@ -628,8 +628,8 @@ export const dbUtils = {
file.wpt.map((wpt) => wpt.clone())
);
} else if (level === ListLevel.WAYPOINT) {
for (let item of items) {
let waypointIndex = (item as ListWaypointItem).getWaypointIndex();
for (const item of items) {
const waypointIndex = (item as ListWaypointItem).getWaypointIndex();
file.replaceWaypoints(waypointIndex + 1, waypointIndex, [
file.wpt[waypointIndex].clone(),
]);
@ -647,7 +647,7 @@ export const dbUtils = {
},
addNewSegment: (fileId: string, trackIndex: number) => {
dbUtils.applyToFile(fileId, (file) => {
let track = file.trk[trackIndex];
const track = file.trk[trackIndex];
track.replaceTrackSegments(track.trkseg.length, track.trkseg.length, [
new TrackSegment(),
]);
@ -662,19 +662,19 @@ export const dbUtils = {
}
applyGlobal((draft) => {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
if (level === ListLevel.FILE) {
file.reverse();
} else if (level === ListLevel.TRACK) {
for (let item of items) {
let trackIndex = (item as ListTrackItem).getTrackIndex();
for (const item of items) {
const trackIndex = (item as ListTrackItem).getTrackIndex();
file.reverseTrack(trackIndex);
}
} else if (level === ListLevel.SEGMENT) {
for (let item of items) {
let trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
for (const item of items) {
const trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
const segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
file.reverseTrackSegment(trackIndex, segmentIndex);
}
}
@ -688,19 +688,19 @@ export const dbUtils = {
}
applyGlobal((draft) => {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
if (level === ListLevel.FILE) {
file.roundTrip();
} else if (level === ListLevel.TRACK) {
for (let item of items) {
let trackIndex = (item as ListTrackItem).getTrackIndex();
for (const item of items) {
const trackIndex = (item as ListTrackItem).getTrackIndex();
file.roundTripTrack(trackIndex);
}
} else if (level === ListLevel.SEGMENT) {
for (let item of items) {
let trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
for (const item of items) {
const trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
const segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
file.roundTripTrackSegment(trackIndex, segmentIndex);
}
}
@ -713,7 +713,7 @@ export const dbUtils = {
let first = true;
let target: ListItem = new ListRootItem();
let targetFile: GPXFile | undefined = undefined;
let toMerge: {
const toMerge: {
trk: Track[];
trkseg: TrackSegment[];
wpt: Waypoint[];
@ -723,8 +723,8 @@ export const dbUtils = {
wpt: [],
};
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
let originalFile = getFile(fileId);
const file = draft.get(fileId);
const originalFile = getFile(fileId);
if (file && originalFile) {
if (level === ListLevel.FILE) {
toMerge.trk.push(...originalFile.trk.map((track) => track.clone()));
@ -742,7 +742,7 @@ export const dbUtils = {
} else {
if (level === ListLevel.TRACK) {
items.forEach((item, index) => {
let trackIndex = (item as ListTrackItem).getTrackIndex();
const trackIndex = (item as ListTrackItem).getTrackIndex();
toMerge.trkseg.splice(
0,
0,
@ -760,8 +760,8 @@ export const dbUtils = {
});
} else if (level === ListLevel.SEGMENT) {
items.forEach((item, index) => {
let trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
const trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
const segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
if (index === items.length - 1) {
// Order is reversed, so the last segment is the first one and the one to keep
target = item;
@ -781,8 +781,8 @@ export const dbUtils = {
});
if (mergeTraces) {
let statistics = get(gpxStatistics);
let speed =
const statistics = get(gpxStatistics);
const speed =
statistics.global.speed.moving > 0 ? statistics.global.speed.moving : undefined;
let startTime: Date | undefined = undefined;
if (speed !== undefined) {
@ -792,7 +792,7 @@ export const dbUtils = {
) {
startTime = statistics.local.points[0].time;
} else {
let index = statistics.local.points.findIndex(
const index = statistics.local.points.findIndex(
(point) => point.time !== undefined
);
if (index !== -1) {
@ -805,7 +805,7 @@ export const dbUtils = {
}
if (toMerge.trk.length > 0 && toMerge.trk[0].trkseg.length > 0) {
let s = new TrackSegment();
const s = new TrackSegment();
toMerge.trk.map((track) => {
track.trkseg.forEach((segment) => {
s.replaceTrackPoints(
@ -822,7 +822,7 @@ export const dbUtils = {
toMerge.trk[0].trkseg = [s];
}
if (toMerge.trkseg.length > 0) {
let s = new TrackSegment();
const s = new TrackSegment();
toMerge.trkseg.forEach((segment) => {
s.replaceTrackPoints(
s.trkpt.length,
@ -842,11 +842,11 @@ export const dbUtils = {
targetFile.replaceTracks(0, targetFile.trk.length - 1, toMerge.trk);
targetFile.replaceWaypoints(0, targetFile.wpt.length - 1, toMerge.wpt);
} else if (target instanceof ListTrackItem) {
let trackIndex = target.getTrackIndex();
const trackIndex = target.getTrackIndex();
targetFile.replaceTrackSegments(trackIndex, 0, -1, toMerge.trkseg);
} else if (target instanceof ListTrackSegmentItem) {
let trackIndex = target.getTrackIndex();
let segmentIndex = target.getSegmentIndex();
const trackIndex = target.getTrackIndex();
const segmentIndex = target.getSegmentIndex();
targetFile.replaceTrackSegments(
trackIndex,
segmentIndex,
@ -863,10 +863,10 @@ export const dbUtils = {
}
applyGlobal((draft) => {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
if (level === ListLevel.FILE) {
let length = file.getNumberOfTrackPoints();
const length = file.getNumberOfTrackPoints();
if (start >= length || end < 0) {
draft.delete(fileId);
} else if (start > 0 || end < length - 1) {
@ -875,13 +875,13 @@ export const dbUtils = {
start -= length;
end -= length;
} else if (level === ListLevel.TRACK) {
let trackIndices = items.map((item) =>
const trackIndices = items.map((item) =>
(item as ListTrackItem).getTrackIndex()
);
file.crop(start, end, trackIndices);
} else if (level === ListLevel.SEGMENT) {
let trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
let segmentIndices = items.map((item) =>
const trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
const segmentIndices = items.map((item) =>
(item as ListTrackSegmentItem).getSegmentIndex()
);
file.crop(start, end, trackIndices, segmentIndices);
@ -894,12 +894,12 @@ export const dbUtils = {
return applyGlobal((draft) => {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
if (level === ListLevel.FILE) {
let file = getFile(fileId);
const file = getFile(fileId);
if (file) {
if (file.trk.length > 1) {
let fileIds = getFileIds(file.trk.length);
const fileIds = getFileIds(file.trk.length);
let closest = file.wpt.map((wpt, wptIndex) => {
const closest = file.wpt.map((wpt, wptIndex) => {
return {
wptIndex: wptIndex,
index: [0],
@ -910,7 +910,7 @@ export const dbUtils = {
track.getSegments().forEach((segment) => {
segment.trkpt.forEach((point) => {
file.wpt.forEach((wpt, wptIndex) => {
let dist = distance(
const dist = distance(
point.getCoordinates(),
wpt.getCoordinates()
);
@ -926,9 +926,9 @@ export const dbUtils = {
});
file.trk.forEach((track, index) => {
let newFile = file.clone();
let tracks = track.trkseg.map((segment, segmentIndex) => {
let t = track.clone();
const newFile = file.clone();
const tracks = track.trkseg.map((segment, segmentIndex) => {
const t = track.clone();
t.replaceTrackSegments(0, track.trkseg.length - 1, [segment]);
if (track.name) {
t.name = `${track.name} (${segmentIndex + 1})`;
@ -949,9 +949,9 @@ export const dbUtils = {
draft.set(newFile._data.id, freeze(newFile));
});
} else if (file.trk.length === 1) {
let fileIds = getFileIds(file.trk[0].trkseg.length);
const fileIds = getFileIds(file.trk[0].trkseg.length);
let closest = file.wpt.map((wpt, wptIndex) => {
const closest = file.wpt.map((wpt, wptIndex) => {
return {
wptIndex: wptIndex,
index: [0],
@ -961,7 +961,7 @@ export const dbUtils = {
file.trk[0].trkseg.forEach((segment, index) => {
segment.trkpt.forEach((point) => {
file.wpt.forEach((wpt, wptIndex) => {
let dist = distance(
const dist = distance(
point.getCoordinates(),
wpt.getCoordinates()
);
@ -976,7 +976,7 @@ export const dbUtils = {
});
file.trk[0].trkseg.forEach((segment, index) => {
let newFile = file.clone();
const newFile = file.clone();
newFile.replaceTrackSegments(0, 0, file.trk[0].trkseg.length - 1, [
segment,
]);
@ -995,13 +995,13 @@ export const dbUtils = {
draft.delete(fileId);
}
} else if (level === ListLevel.TRACK) {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
for (let item of items) {
let trackIndex = (item as ListTrackItem).getTrackIndex();
let track = file.trk[trackIndex];
let tracks = track.trkseg.map((segment, segmentIndex) => {
let t = track.clone();
for (const item of items) {
const trackIndex = (item as ListTrackItem).getTrackIndex();
const track = file.trk[trackIndex];
const tracks = track.trkseg.map((segment, segmentIndex) => {
const t = track.clone();
t.replaceTrackSegments(0, track.trkseg.length - 1, [segment]);
if (track.name) {
t.name = `${track.name} (${segmentIndex + 1})`;
@ -1022,16 +1022,16 @@ export const dbUtils = {
coordinates: Coordinates,
trkptIndex?: number
) {
let splitType = get(splitAs);
const splitType = get(splitAs);
return applyGlobal((draft) => {
let file = getFile(fileId);
const file = getFile(fileId);
if (file) {
let segment = file.trk[trackIndex].trkseg[segmentIndex];
const segment = file.trk[trackIndex].trkseg[segmentIndex];
let minIndex = 0;
if (trkptIndex === undefined) {
// Find the point closest to split
let closest = getClosestLinePoint(segment.trkpt, coordinates);
const closest = getClosestLinePoint(segment.trkpt, coordinates);
minIndex = closest._data.index;
} else {
minIndex = trkptIndex;
@ -1048,29 +1048,29 @@ export const dbUtils = {
});
if (splitType === SplitType.FILES) {
let newFile = draft.get(fileId);
const newFile = draft.get(fileId);
if (newFile) {
newFile.crop(0, absoluteIndex);
let newFile2 = file.clone();
const newFile2 = file.clone();
newFile2._data.id = getFileIds(1)[0];
newFile2.crop(absoluteIndex, file.getNumberOfTrackPoints() - 1);
draft.set(newFile2._data.id, freeze(newFile2));
}
} else if (splitType === SplitType.TRACKS) {
let newFile = draft.get(fileId);
const newFile = draft.get(fileId);
if (newFile) {
let start = file.trk[trackIndex].clone();
const start = file.trk[trackIndex].clone();
start.crop(0, absoluteIndex);
let end = file.trk[trackIndex].clone();
const end = file.trk[trackIndex].clone();
end.crop(absoluteIndex, file.trk[trackIndex].getNumberOfTrackPoints() - 1);
newFile.replaceTracks(trackIndex, trackIndex, [start, end]);
}
} else if (splitType === SplitType.SEGMENTS) {
let newFile = draft.get(fileId);
const newFile = draft.get(fileId);
if (newFile) {
let start = segment.clone();
const start = segment.clone();
start.crop(0, minIndex);
let end = segment.clone();
const end = segment.clone();
end.crop(minIndex, segment.trkpt.length - 1);
newFile.replaceTrackSegments(trackIndex, segmentIndex, segmentIndex, [
start,
@ -1092,12 +1092,12 @@ export const dbUtils = {
}
applyGlobal((draft) => {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
if (level === ListLevel.FILE) {
file.clean(bounds, inside, deleteTrackPoints, deleteWaypoints);
} else if (level === ListLevel.TRACK) {
let trackIndices = items.map((item) =>
const trackIndices = items.map((item) =>
(item as ListTrackItem).getTrackIndex()
);
file.clean(
@ -1108,8 +1108,8 @@ export const dbUtils = {
trackIndices
);
} else if (level === ListLevel.SEGMENT) {
let trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
let segmentIndices = items.map((item) =>
const trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
const segmentIndices = items.map((item) =>
(item as ListTrackSegmentItem).getSegmentIndex()
);
file.clean(
@ -1123,7 +1123,7 @@ export const dbUtils = {
} else if (level === ListLevel.WAYPOINTS) {
file.clean(bounds, inside, false, deleteWaypoints);
} else if (level === ListLevel.WAYPOINT) {
let waypointIndices = items.map((item) =>
const waypointIndices = items.map((item) =>
(item as ListWaypointItem).getWaypointIndex()
);
file.clean(bounds, inside, false, deleteWaypoints, [], [], waypointIndices);
@ -1137,15 +1137,15 @@ export const dbUtils = {
return;
}
applyGlobal((draft) => {
let allItems = Array.from(itemsAndPoints.keys());
const allItems = Array.from(itemsAndPoints.keys());
applyToOrderedItemsFromFile(allItems, (fileId, level, items) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
for (let item of items) {
for (const item of items) {
if (item instanceof ListTrackSegmentItem) {
let trackIndex = item.getTrackIndex();
let segmentIndex = item.getSegmentIndex();
let points = itemsAndPoints.get(item);
const trackIndex = item.getTrackIndex();
const segmentIndex = item.getSegmentIndex();
const points = itemsAndPoints.get(item);
if (points) {
file.replaceTrackPoints(
trackIndex,
@ -1164,14 +1164,14 @@ export const dbUtils = {
});
},
addOrUpdateWaypoint: (waypoint: WaypointType, item?: ListWaypointItem) => {
let m = get(map);
const m = get(map);
if (m === null) {
return;
}
getElevation([waypoint.attributes]).then((elevation) => {
if (item) {
dbUtils.applyToFile(item.getFileId(), (file) => {
let wpt = file.wpt[item.getWaypointIndex()];
const wpt = file.wpt[item.getWaypointIndex()];
wpt.name = waypoint.name;
wpt.desc = waypoint.desc;
wpt.cmt = waypoint.cmt;
@ -1181,13 +1181,13 @@ export const dbUtils = {
wpt.ele = elevation[0];
});
} else {
let fileIds = new Set<string>();
const fileIds = new Set<string>();
get(selection)
.getSelected()
.forEach((item) => {
fileIds.add(item.getFileId());
});
let wpt = new Waypoint(waypoint);
const wpt = new Waypoint(waypoint);
wpt.ele = elevation[0];
dbUtils.applyToFiles(Array.from(fileIds), (file) =>
file.replaceWaypoints(file.wpt.length, file.wpt.length, [wpt])
@ -1201,7 +1201,7 @@ export const dbUtils = {
}
applyGlobal((draft) => {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file && (level === ListLevel.FILE || level === ListLevel.TRACK)) {
if (level === ListLevel.FILE) {
file.setStyle(style);
@ -1209,8 +1209,8 @@ export const dbUtils = {
if (items.length === file.trk.length) {
file.setStyle(style);
} else {
for (let item of items) {
let trackIndex = (item as ListTrackItem).getTrackIndex();
for (const item of items) {
const trackIndex = (item as ListTrackItem).getTrackIndex();
file.trk[trackIndex].setStyle(style);
}
}
@ -1225,25 +1225,25 @@ export const dbUtils = {
}
applyGlobal((draft) => {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
if (level === ListLevel.FILE) {
file.setHidden(hidden);
} else if (level === ListLevel.TRACK) {
let trackIndices = items.map((item) =>
const trackIndices = items.map((item) =>
(item as ListTrackItem).getTrackIndex()
);
file.setHidden(hidden, trackIndices);
} else if (level === ListLevel.SEGMENT) {
let trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
let segmentIndices = items.map((item) =>
const trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
const segmentIndices = items.map((item) =>
(item as ListTrackSegmentItem).getSegmentIndex()
);
file.setHidden(hidden, trackIndices, segmentIndices);
} else if (level === ListLevel.WAYPOINTS) {
file.setHiddenWaypoints(hidden);
} else if (level === ListLevel.WAYPOINT) {
let waypointIndices = items.map((item) =>
const waypointIndices = items.map((item) =>
(item as ListWaypointItem).getWaypointIndex()
);
file.setHiddenWaypoints(hidden, waypointIndices);
@ -1261,17 +1261,17 @@ export const dbUtils = {
if (level === ListLevel.FILE) {
draft.delete(fileId);
} else {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
if (level === ListLevel.TRACK) {
for (let item of items) {
let trackIndex = (item as ListTrackItem).getTrackIndex();
for (const item of items) {
const trackIndex = (item as ListTrackItem).getTrackIndex();
file.replaceTracks(trackIndex, trackIndex, []);
}
} else if (level === ListLevel.SEGMENT) {
for (let item of items) {
let trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
for (const item of items) {
const trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
const segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
file.replaceTrackSegments(
trackIndex,
segmentIndex,
@ -1282,8 +1282,8 @@ export const dbUtils = {
} else if (level === ListLevel.WAYPOINTS) {
file.replaceWaypoints(0, file.wpt.length - 1, []);
} else if (level === ListLevel.WAYPOINT) {
for (let item of items) {
let waypointIndex = (item as ListWaypointItem).getWaypointIndex();
for (const item of items) {
const waypointIndex = (item as ListWaypointItem).getWaypointIndex();
file.replaceWaypoints(waypointIndex, waypointIndex, []);
}
}
@ -1296,21 +1296,21 @@ export const dbUtils = {
if (get(selection).size === 0) {
return;
}
let points: (TrackPoint | Waypoint)[] = [];
const points: (TrackPoint | Waypoint)[] = [];
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = fileState.get(fileId);
const file = fileState.get(fileId);
if (file) {
if (level === ListLevel.FILE) {
points.push(...file.getTrackPoints());
points.push(...file.wpt);
} else if (level === ListLevel.TRACK) {
let trackIndices = items.map((item) => (item as ListTrackItem).getTrackIndex());
const trackIndices = items.map((item) => (item as ListTrackItem).getTrackIndex());
trackIndices.forEach((trackIndex) => {
points.push(...file.trk[trackIndex].getTrackPoints());
});
} else if (level === ListLevel.SEGMENT) {
let trackIndex = (items[0] as ListTrackSegmentItem).getTrackIndex();
let segmentIndices = items.map((item) =>
const trackIndex = (items[0] as ListTrackSegmentItem).getTrackIndex();
const segmentIndices = items.map((item) =>
(item as ListTrackSegmentItem).getSegmentIndex()
);
segmentIndices.forEach((segmentIndex) => {
@ -1319,7 +1319,7 @@ export const dbUtils = {
} else if (level === ListLevel.WAYPOINTS) {
points.push(...file.wpt);
} else if (level === ListLevel.WAYPOINT) {
let waypointIndices = items.map((item) =>
const waypointIndices = items.map((item) =>
(item as ListWaypointItem).getWaypointIndex()
);
points.push(...waypointIndices.map((waypointIndex) => file.wpt[waypointIndex]));
@ -1334,25 +1334,25 @@ export const dbUtils = {
getElevation(points).then((elevations) => {
applyGlobal((draft) => {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
const file = draft.get(fileId);
if (file) {
if (level === ListLevel.FILE) {
file.addElevation(elevations);
} else if (level === ListLevel.TRACK) {
let trackIndices = items.map((item) =>
const trackIndices = items.map((item) =>
(item as ListTrackItem).getTrackIndex()
);
file.addElevation(elevations, trackIndices, undefined, []);
} else if (level === ListLevel.SEGMENT) {
let trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
let segmentIndices = items.map((item) =>
const trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
const segmentIndices = items.map((item) =>
(item as ListTrackSegmentItem).getSegmentIndex()
);
file.addElevation(elevations, trackIndices, segmentIndices, []);
} else if (level === ListLevel.WAYPOINTS) {
file.addElevation(elevations, [], [], undefined);
} else if (level === ListLevel.WAYPOINT) {
let waypointIndices = items.map((item) =>
const waypointIndices = items.map((item) =>
(item as ListWaypointItem).getWaypointIndex()
);
file.addElevation(elevations, [], [], waypointIndices);
@ -1380,7 +1380,7 @@ export const dbUtils = {
// undo-redo
undo: () => {
if (get(canUndo)) {
let index = get(patchIndex);
const index = get(patchIndex);
db.patches.get(index).then((patch) => {
if (patch) {
applyPatch(patch.inversePatch);
@ -1391,7 +1391,7 @@ export const dbUtils = {
},
redo: () => {
if (get(canRedo)) {
let index = get(patchIndex) + 1;
const index = get(patchIndex) + 1;
db.patches.get(index).then((patch) => {
if (patch) {
applyPatch(patch.patch);

View file

@ -37,9 +37,9 @@ export const slicedGPXStatistics: Writable<[GPXStatistics, number, number] | und
writable(undefined);
export function updateGPXData() {
let statistics = new GPXStatistics();
const statistics = new GPXStatistics();
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let stats = getStatistics(fileId);
const stats = getStatistics(fileId);
if (stats) {
let first = true;
items.forEach((item) => {
@ -56,21 +56,21 @@ export function updateGPXData() {
gpxStatistics.set(statistics);
}
let unsubscribes: Map<string, () => void> = new Map();
const unsubscribes: Map<string, () => void> = new Map();
selection.subscribe(($selection) => {
// Maintain up-to-date statistics for the current selection
updateGPXData();
while (unsubscribes.size > 0) {
let [fileId, unsubscribe] = unsubscribes.entries().next().value;
const [fileId, unsubscribe] = unsubscribes.entries().next().value;
unsubscribe();
unsubscribes.delete(fileId);
}
$selection.forEach((item) => {
let fileId = item.getFileId();
const fileId = item.getFileId();
if (!unsubscribes.has(fileId)) {
let fileObserver = get(fileObservers).get(fileId);
const fileObserver = get(fileObservers).get(fileId);
if (fileObserver) {
let first = true;
unsubscribes.set(
@ -111,8 +111,8 @@ derived([targetMapBounds, map], (x) => x).subscribe(([bounds, $map]) => {
return;
}
let currentZoom = $map.getZoom();
let currentBounds = $map.getBounds();
const currentZoom = $map.getZoom();
const currentBounds = $map.getBounds();
if (
bounds.total !== get(fileObservers).size &&
currentBounds &&
@ -167,16 +167,16 @@ export function updateTargetMapBounds(
}
export function centerMapOnSelection() {
let selected = get(selection).getSelected();
let bounds = new mapboxgl.LngLatBounds();
const selected = get(selection).getSelected();
const bounds = new mapboxgl.LngLatBounds();
if (selected.find((item) => item instanceof ListWaypointItem)) {
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = getFile(fileId);
const file = getFile(fileId);
if (file) {
items.forEach((item) => {
if (item instanceof ListWaypointItem) {
let waypoint = file.wpt[item.getWaypointIndex()];
const waypoint = file.wpt[item.getWaypointIndex()];
if (waypoint) {
bounds.extend([waypoint.getLongitude(), waypoint.getLatitude()]);
}
@ -185,7 +185,7 @@ export function centerMapOnSelection() {
}
});
} else {
let selectionBounds = get(gpxStatistics).global.bounds;
const selectionBounds = get(gpxStatistics).global.bounds;
bounds.setNorthEast(selectionBounds.northEast);
bounds.setSouthWest(selectionBounds.southWest);
}
@ -218,13 +218,13 @@ export const streetViewEnabled = writable(false);
export function newGPXFile() {
const newFileName = get(_)('menu.new_file');
let file = new GPXFile();
const file = new GPXFile();
let maxNewFileNumber = 0;
get(fileObservers).forEach((f) => {
let file = get(f)?.file;
const file = get(f)?.file;
if (file && file.metadata.name && file.metadata.name.startsWith(newFileName)) {
let number = parseInt(file.metadata.name.split(' ').pop() ?? '0');
const number = parseInt(file.metadata.name.split(' ').pop() ?? '0');
if (!isNaN(number) && number > maxNewFileNumber) {
maxNewFileNumber = number;
}
@ -237,7 +237,7 @@ export function newGPXFile() {
}
export function createFile() {
let file = newGPXFile();
const file = newGPXFile();
dbUtils.add(file);
@ -260,27 +260,27 @@ export function triggerFileInput() {
}
export async function loadFiles(list: FileList | File[]) {
let files: GPXFile[] = [];
const files: GPXFile[] = [];
for (let i = 0; i < list.length; i++) {
let file = await loadFile(list[i]);
const file = await loadFile(list[i]);
if (file) {
files.push(file);
}
}
let ids = dbUtils.addMultiple(files);
const ids = dbUtils.addMultiple(files);
initTargetMapBounds(ids);
selectFileWhenLoaded(ids[0]);
}
export async function loadFile(file: File): Promise<GPXFile | null> {
let result = await new Promise<GPXFile | null>((resolve) => {
const result = await new Promise<GPXFile | null>((resolve) => {
const reader = new FileReader();
reader.onload = () => {
let data = reader.result?.toString() ?? null;
const data = reader.result?.toString() ?? null;
if (data) {
let gpx = parseGPX(data);
const gpx = parseGPX(data);
if (gpx.metadata === undefined) {
gpx.metadata = {};
}
@ -309,17 +309,17 @@ export function selectFileWhenLoaded(fileId: string) {
}
export function updateSelectionFromKey(down: boolean, shift: boolean) {
let selected = get(selection).getSelected();
const selected = get(selection).getSelected();
if (selected.length === 0) {
return;
}
let next: ListItem | undefined = undefined;
if (selected[0] instanceof ListFileItem) {
let order = get(fileOrder);
const order = get(fileOrder);
let limitIndex: number | undefined = undefined;
selected.forEach((item) => {
let index = order.indexOf(item.getFileId());
const index = order.indexOf(item.getFileId());
if (
limitIndex === undefined ||
(down && index > limitIndex) ||
@ -355,11 +355,11 @@ export function updateSelectionFromKey(down: boolean, shift: boolean) {
selected[0] instanceof ListTrackItem &&
selected[selected.length - 1] instanceof ListTrackItem
) {
let fileId = selected[0].getFileId();
let file = getFile(fileId);
const fileId = selected[0].getFileId();
const file = getFile(fileId);
if (file) {
let numberOfTracks = file.trk.length;
let trackIndex = down
const numberOfTracks = file.trk.length;
const trackIndex = down
? selected[selected.length - 1].getTrackIndex()
: selected[0].getTrackIndex();
if (down && trackIndex < numberOfTracks - 1) {
@ -372,12 +372,12 @@ export function updateSelectionFromKey(down: boolean, shift: boolean) {
selected[0] instanceof ListTrackSegmentItem &&
selected[selected.length - 1] instanceof ListTrackSegmentItem
) {
let fileId = selected[0].getFileId();
let file = getFile(fileId);
const fileId = selected[0].getFileId();
const file = getFile(fileId);
if (file) {
let trackIndex = selected[0].getTrackIndex();
let numberOfSegments = file.trk[trackIndex].trkseg.length;
let segmentIndex = down
const trackIndex = selected[0].getTrackIndex();
const numberOfSegments = file.trk[trackIndex].trkseg.length;
const segmentIndex = down
? selected[selected.length - 1].getSegmentIndex()
: selected[0].getSegmentIndex();
if (down && segmentIndex < numberOfSegments - 1) {
@ -390,11 +390,11 @@ export function updateSelectionFromKey(down: boolean, shift: boolean) {
selected[0] instanceof ListWaypointItem &&
selected[selected.length - 1] instanceof ListWaypointItem
) {
let fileId = selected[0].getFileId();
let file = getFile(fileId);
const fileId = selected[0].getFileId();
const file = getFile(fileId);
if (file) {
let numberOfWaypoints = file.wpt.length;
let waypointIndex = down
const numberOfWaypoints = file.wpt.length;
const waypointIndex = down
? selected[selected.length - 1].getWaypointIndex()
: selected[0].getWaypointIndex();
if (down && waypointIndex < numberOfWaypoints - 1) {
@ -465,9 +465,9 @@ export const allHidden = writable(false);
export function updateAllHidden() {
let hidden = true;
applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = getFile(fileId);
const file = getFile(fileId);
if (file) {
for (let item of items) {
for (const item of items) {
if (!hidden) {
return;
}

View file

@ -36,9 +36,9 @@ export function distancePerHourToSecondsPerDistance(value: number) {
}
export function secondsToHHMMSS(value: number) {
var hours = Math.floor(value / 3600);
var minutes = Math.floor(value / 60) % 60;
var seconds = Math.min(59, Math.round(value % 60));
const hours = Math.floor(value / 3600);
const minutes = Math.floor(value / 60) % 60;
const seconds = Math.min(59, Math.round(value % 60));
return [hours, minutes, seconds]
.map((v) => (v < 10 ? '0' + v : v))

View file

@ -78,7 +78,7 @@ export function getClosestLinePoint(
let closest = points[0];
let closestDist = Number.MAX_VALUE;
for (let i = 0; i < points.length - 1; i++) {
let dist = crossarcDistance(points[i], points[i + 1], point);
const dist = crossarcDistance(points[i], points[i + 1], point);
if (dist < closestDist) {
closestDist = dist;
if (distance(points[i], point) <= distance(points[i + 1], point)) {
@ -101,21 +101,21 @@ export function getElevation(
ELEVATION_ZOOM: number = 13,
tileSize = 512
): Promise<number[]> {
let coordinates = points.map((point) =>
const coordinates = points.map((point) =>
point instanceof TrackPoint || point instanceof Waypoint ? point.getCoordinates() : point
);
let bbox = new mapboxgl.LngLatBounds();
const bbox = new mapboxgl.LngLatBounds();
coordinates.forEach((coord) => bbox.extend(coord));
let tiles = coordinates.map((coord) =>
const tiles = coordinates.map((coord) =>
tilebelt.pointToTile(coord.lon, coord.lat, ELEVATION_ZOOM)
);
let uniqueTiles = Array.from(new Set(tiles.map((tile) => tile.join(',')))).map((tile) =>
const uniqueTiles = Array.from(new Set(tiles.map((tile) => tile.join(',')))).map((tile) =>
tile.split(',').map((x) => parseInt(x))
);
let pngs = new Map<string, any>();
const pngs = new Map<string, any>();
let promises = uniqueTiles.map((tile) =>
const promises = uniqueTiles.map((tile) =>
fetch(
`https://api.mapbox.com/v4/mapbox.mapbox-terrain-dem-v1/${ELEVATION_ZOOM}/${tile[0]}/${tile[1]}@2x.pngraw?access_token=${PUBLIC_MAPBOX_TOKEN}`,
{ cache: 'force-cache' }
@ -124,7 +124,7 @@ export function getElevation(
.then(
(buffer) =>
new Promise((resolve) => {
let png = new PNGReader(new Uint8Array(buffer));
const png = new PNGReader(new Uint8Array(buffer));
png.parse((err, png) => {
if (err) {
resolve(false); // Also resolve so that Promise.all doesn't fail
@ -139,20 +139,20 @@ export function getElevation(
return Promise.all(promises).then(() =>
coordinates.map((coord, index) => {
let tile = tiles[index];
let png = pngs.get(tile.join(','));
const tile = tiles[index];
const png = pngs.get(tile.join(','));
if (!png) {
return 0;
}
let tf = tilebelt.pointToTileFraction(coord.lon, coord.lat, ELEVATION_ZOOM);
let x = tileSize * (tf[0] - tile[0]);
let y = tileSize * (tf[1] - tile[1]);
let _x = Math.floor(x);
let _y = Math.floor(y);
let dx = x - _x;
let dy = y - _y;
const tf = tilebelt.pointToTileFraction(coord.lon, coord.lat, ELEVATION_ZOOM);
const x = tileSize * (tf[0] - tile[0]);
const y = tileSize * (tf[1] - tile[1]);
const _x = Math.floor(x);
const _y = Math.floor(y);
const dx = x - _x;
const dy = y - _y;
const p00 = png.getPixel(_x, _y);
const p01 = png.getPixel(_x, _y + (_y + 1 == tileSize ? 0 : 1));
@ -162,10 +162,10 @@ export function getElevation(
_y + (_y + 1 == tileSize ? 0 : 1)
);
let ele00 = -10000 + (p00[0] * 256 * 256 + p00[1] * 256 + p00[2]) * 0.1;
let ele01 = -10000 + (p01[0] * 256 * 256 + p01[1] * 256 + p01[2]) * 0.1;
let ele10 = -10000 + (p10[0] * 256 * 256 + p10[1] * 256 + p10[2]) * 0.1;
let ele11 = -10000 + (p11[0] * 256 * 256 + p11[1] * 256 + p11[2]) * 0.1;
const ele00 = -10000 + (p00[0] * 256 * 256 + p00[1] * 256 + p00[2]) * 0.1;
const ele01 = -10000 + (p01[0] * 256 * 256 + p01[1] * 256 + p01[2]) * 0.1;
const ele10 = -10000 + (p10[0] * 256 * 256 + p10[1] * 256 + p10[2]) * 0.1;
const ele11 = -10000 + (p11[0] * 256 * 256 + p11[1] * 256 + p11[2]) * 0.1;
return (
ele00 * (1 - dx) * (1 - dy) +
@ -177,9 +177,9 @@ export function getElevation(
);
}
let previousCursors: string[] = [];
const previousCursors: string[] = [];
export function setCursor(cursor: string) {
let m = get(map);
const m = get(map);
if (m) {
previousCursors.push(m.getCanvas().style.cursor);
m.getCanvas().style.cursor = cursor;
@ -187,7 +187,7 @@ export function setCursor(cursor: string) {
}
export function resetCursor() {
let m = get(map);
const m = get(map);
if (m) {
m.getCanvas().style.cursor = previousCursors.pop() ?? '';
}

View file

@ -15,9 +15,9 @@ export async function load({ params }) {
const { language } = params;
const guideTitles: Record<string, string> = {};
for (let guide of Object.keys(guides)) {
for (const guide of Object.keys(guides)) {
guideTitles[guide] = (await getModule(language, guide)).metadata.title;
for (let subguide of guides[guide]) {
for (const subguide of guides[guide]) {
guideTitles[`${guide}/${subguide}`] = (
await getModule(language, `${guide}/${subguide}`)
).metadata.title;