Format with eslint
This commit is contained in:
parent
24ffdb5d9c
commit
a2cd6ee681
24 changed files with 479 additions and 483 deletions
|
@ -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,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
134
gpx/src/gpx.ts
134
gpx/src/gpx.ts
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}%)`;
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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') {
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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 = {};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 [];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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() ?? '';
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue