store stats outside of gpx object

This commit is contained in:
vcoppe
2024-05-03 22:15:47 +02:00
parent 22884b3a8b
commit 619849f987
6 changed files with 170 additions and 223 deletions

View File

@@ -19,9 +19,8 @@ export abstract class GPXTreeElement<T extends GPXTreeElement<any>> {
abstract getStartTimestamp(): Date;
abstract getEndTimestamp(): Date;
abstract getStatistics(): GPXStatistics;
abstract getTrackPoints(): TrackPoint[];
abstract getTrackPointsAndStatistics(): { points: TrackPoint[], point_statistics: TrackPointStatistics, statistics: GPXStatistics };
abstract getStatistics(): GPXStatistics;
abstract getSegments(): TrackSegment[];
abstract toGeoJSON(): GeoJSON.Feature | GeoJSON.Feature[] | GeoJSON.FeatureCollection | GeoJSON.FeatureCollection[];
@@ -85,40 +84,6 @@ abstract class GPXTreeNode<T extends GPXTreeElement<any>> extends GPXTreeElement
return statistics;
}
getTrackPointsAndStatistics(): { points: TrackPoint[], point_statistics: TrackPointStatistics, statistics: GPXStatistics } {
let points: TrackPoint[] = [];
let point_statistics: TrackPointStatistics = {
distance: [],
time: [],
speed: [],
elevation: {
smoothed: [],
gain: [],
loss: [],
},
slope: [],
};
let statistics = new GPXStatistics();
for (let child of this.getChildren()) {
let childData = child.getTrackPointsAndStatistics();
points = points.concat(childData.points);
point_statistics.distance = point_statistics.distance.concat(childData.point_statistics.distance.map((distance) => distance + statistics.distance.total));
point_statistics.time = point_statistics.time.concat(childData.point_statistics.time.map((time) => time + statistics.time.total));
point_statistics.elevation.gain = point_statistics.elevation.gain.concat(childData.point_statistics.elevation.gain.map((gain) => gain + statistics.elevation.gain));
point_statistics.elevation.loss = point_statistics.elevation.loss.concat(childData.point_statistics.elevation.loss.map((loss) => loss + statistics.elevation.loss));
point_statistics.speed = point_statistics.speed.concat(childData.point_statistics.speed);
point_statistics.elevation.smoothed = point_statistics.elevation.smoothed.concat(childData.point_statistics.elevation.smoothed);
point_statistics.slope = point_statistics.slope.concat(childData.point_statistics.slope);
statistics.mergeWith(childData.statistics);
}
return { points, point_statistics, statistics };
}
getSegments(): TrackSegment[] {
return this.getChildren().flatMap((child) => child.getSegments());
}
@@ -165,13 +130,8 @@ export class GPXFile extends GPXTreeNode<Track>{
if (gpx) {
this.attributes = gpx.attributes
this.metadata = gpx.metadata;
if (gpx instanceof GPXFile) {
this.wpt = gpx.wpt;
this.trk = gpx.trk;
} else {
this.wpt = gpx.wpt ? gpx.wpt.map((waypoint) => new Waypoint(waypoint)) : [];
this.trk = gpx.trk ? gpx.trk.map((track) => new Track(track)) : [];
}
this.wpt = gpx.wpt ? gpx.wpt.map((waypoint) => new Waypoint(waypoint)) : [];
this.trk = gpx.trk ? gpx.trk.map((track) => new Track(track)) : [];
if (gpx.hasOwnProperty('_data')) {
this._data = gpx._data;
}
@@ -234,11 +194,7 @@ export class Track extends GPXTreeNode<TrackSegment> {
this.src = track.src;
this.link = track.link;
this.type = track.type;
if (track instanceof Track) {
this.trkseg = track.trkseg;
} else {
this.trkseg = track.trkseg ? track.trkseg.map((seg) => new TrackSegment(seg)) : [];
}
this.trkseg = track.trkseg ? track.trkseg.map((seg) => new TrackSegment(seg)) : [];
this.extensions = cloneJSON(track.extensions);
if (track.hasOwnProperty('_data')) {
this._data = cloneJSON(track._data);
@@ -301,43 +257,26 @@ export class Track extends GPXTreeNode<TrackSegment> {
// A class that represents a TrackSegment in a GPX file
export class TrackSegment extends GPXTreeLeaf {
trkpt: TrackPoint[];
trkptStatistics: TrackPointStatistics;
statistics: GPXStatistics;
constructor(segment?: TrackSegmentType | TrackSegment) {
super();
if (segment) {
if (segment instanceof TrackSegment) {
this.trkpt = segment.trkpt;
} else {
this.trkpt = segment.trkpt.map((point) => new TrackPoint(point));
}
this.trkpt = segment.trkpt.map((point) => new TrackPoint(point));
if (segment.hasOwnProperty('_data')) {
this._data = cloneJSON(segment._data);
}
} else {
this.trkpt = [];
}
this._computeStatistics();
}
_computeStatistics(): void {
_computeStatistics(): GPXStatistics {
let statistics = new GPXStatistics();
let trkptStatistics: TrackPointStatistics = {
distance: [],
time: [],
speed: [],
elevation: {
smoothed: [],
gain: [],
loss: [],
},
slope: [],
};
trkptStatistics.elevation.smoothed = this._computeSmoothedElevation();
trkptStatistics.slope = this._computeSlope();
statistics.local.points = this.trkpt;
statistics.local.elevation.smoothed = this._computeSmoothedElevation();
statistics.local.slope = this._computeSlope();
const points = this.trkpt;
for (let i = 0; i < points.length; i++) {
@@ -348,29 +287,29 @@ export class TrackSegment extends GPXTreeLeaf {
if (i > 0) {
dist = distance(points[i - 1].getCoordinates(), points[i].getCoordinates()) / 1000;
statistics.distance.total += dist;
statistics.global.distance.total += dist;
}
trkptStatistics.distance.push(statistics.distance.total);
statistics.local.distance.push(statistics.global.distance.total);
// elevation
if (i > 0) {
const ele = trkptStatistics.elevation.smoothed[i] - trkptStatistics.elevation.smoothed[i - 1];
const ele = statistics.local.elevation.smoothed[i] - statistics.local.elevation.smoothed[i - 1];
if (ele > 0) {
statistics.elevation.gain += ele;
statistics.global.elevation.gain += ele;
} else {
statistics.elevation.loss -= ele;
statistics.global.elevation.loss -= ele;
}
}
trkptStatistics.elevation.gain.push(statistics.elevation.gain);
trkptStatistics.elevation.loss.push(statistics.elevation.loss);
statistics.local.elevation.gain.push(statistics.global.elevation.gain);
statistics.local.elevation.loss.push(statistics.global.elevation.loss);
// time
if (points[0].time !== undefined && points[i].time !== undefined) {
const time = (points[i].time.getTime() - points[0].time.getTime()) / 1000;
trkptStatistics.time.push(time);
statistics.local.time.push(time);
}
// speed
@@ -380,26 +319,25 @@ export class TrackSegment extends GPXTreeLeaf {
speed = dist / (time / 3600);
if (speed >= 0.5) {
statistics.distance.moving += dist;
statistics.time.moving += time;
statistics.global.distance.moving += dist;
statistics.global.time.moving += time;
}
}
// bounds
statistics.bounds.southWest.lat = Math.min(statistics.bounds.southWest.lat, points[i].attributes.lat);
statistics.bounds.southWest.lon = Math.max(statistics.bounds.southWest.lon, points[i].attributes.lon);
statistics.bounds.northEast.lat = Math.max(statistics.bounds.northEast.lat, points[i].attributes.lat);
statistics.bounds.northEast.lon = Math.min(statistics.bounds.northEast.lon, points[i].attributes.lon);
statistics.global.bounds.southWest.lat = Math.min(statistics.global.bounds.southWest.lat, points[i].attributes.lat);
statistics.global.bounds.southWest.lon = Math.max(statistics.global.bounds.southWest.lon, points[i].attributes.lon);
statistics.global.bounds.northEast.lat = Math.max(statistics.global.bounds.northEast.lat, points[i].attributes.lat);
statistics.global.bounds.northEast.lon = Math.min(statistics.global.bounds.northEast.lon, points[i].attributes.lon);
}
statistics.time.total = trkptStatistics.time[trkptStatistics.time.length - 1];
statistics.speed.total = statistics.distance.total / (statistics.time.total / 3600);
statistics.speed.moving = statistics.distance.moving / (statistics.time.moving / 3600);
statistics.global.time.total = statistics.local.time[statistics.local.time.length - 1];
statistics.global.speed.total = statistics.global.distance.total / (statistics.global.time.total / 3600);
statistics.global.speed.moving = statistics.global.distance.moving / (statistics.global.time.moving / 3600);
trkptStatistics.speed = distanceWindowSmoothingWithDistanceAccumulator(points, 200, (accumulated, start, end) => (points[start].time && points[end].time) ? 3600 * accumulated / (points[end].time.getTime() - points[start].time.getTime()) : undefined);
statistics.local.speed = distanceWindowSmoothingWithDistanceAccumulator(points, 200, (accumulated, start, end) => (points[start].time && points[end].time) ? 3600 * accumulated / (points[end].time.getTime() - points[start].time.getTime()) : undefined);
this.statistics = statistics;
this.trkptStatistics = trkptStatistics;
return statistics;
}
_computeSmoothedElevation(): number[] {
@@ -461,15 +399,7 @@ export class TrackSegment extends GPXTreeLeaf {
}
getStatistics(): GPXStatistics {
return this.statistics;
}
getTrackPointsAndStatistics(): { points: TrackPoint[], point_statistics: TrackPointStatistics, statistics: GPXStatistics } {
return {
points: this.trkpt,
point_statistics: this.trkptStatistics,
statistics: this.statistics,
};
return this._computeStatistics();
}
getSegments(): TrackSegment[] {
@@ -509,7 +439,6 @@ export class TrackPoint {
_data: { [key: string]: any } = {};
constructor(point: TrackPointType | TrackPoint) {
this.attributes = point.attributes;
this.attributes = point.attributes;
this.ele = point.ele;
this.time = point.time;
@@ -602,9 +531,7 @@ export class Waypoint {
constructor(waypoint: WaypointType | Waypoint) {
this.attributes = waypoint.attributes;
this.ele = waypoint.ele;
if (waypoint.time) {
this.time = new Date(waypoint.time.getTime());
}
this.time = waypoint.time;
this.name = waypoint.name;
this.cmt = waypoint.cmt;
this.desc = waypoint.desc;
@@ -637,88 +564,116 @@ export class Waypoint {
}
export class GPXStatistics {
distance: {
moving: number;
total: number;
global: {
distance: {
moving: number,
total: number,
},
time: {
moving: number,
total: number,
},
speed: {
moving: number,
total: number,
},
elevation: {
gain: number,
loss: number,
},
bounds: {
southWest: Coordinates,
northEast: Coordinates,
},
};
time: {
moving: number;
total: number;
local: {
points: TrackPoint[],
distance: number[],
time: number[],
speed: number[],
elevation: {
smoothed: number[],
gain: number[],
loss: number[],
},
slope: number[],
};
speed: {
moving: number;
total: number;
};
elevation: {
gain: number;
loss: number;
};
bounds: {
southWest: Coordinates;
northEast: Coordinates;
}
constructor() {
this.distance = {
moving: 0,
total: 0,
};
this.time = {
moving: 0,
total: 0,
};
this.speed = {
moving: 0,
total: 0,
};
this.elevation = {
gain: 0,
loss: 0,
};
this.bounds = {
southWest: {
lat: 90,
lon: -180,
this.global = {
distance: {
moving: 0,
total: 0,
},
northEast: {
lat: -90,
lon: 180,
time: {
moving: 0,
total: 0,
},
speed: {
moving: 0,
total: 0,
},
elevation: {
gain: 0,
loss: 0,
},
bounds: {
southWest: {
lat: 90,
lon: -180,
},
northEast: {
lat: -90,
lon: 180,
},
},
};
this.local = {
points: [],
distance: [],
time: [],
speed: [],
elevation: {
smoothed: [],
gain: [],
loss: [],
},
slope: [],
};
}
mergeWith(other: GPXStatistics): void {
this.distance.total += other.distance.total;
this.distance.moving += other.distance.moving;
this.time.total += other.time.total;
this.time.moving += other.time.moving;
this.local.points = this.local.points.concat(other.local.points);
this.speed.moving = this.distance.moving / (this.time.moving / 3600);
this.speed.total = this.distance.total / (this.time.total / 3600);
this.local.distance = this.local.distance.concat(other.local.distance.map((distance) => distance + this.global.distance.total));
this.local.time = this.local.time.concat(other.local.time.map((time) => time + this.global.time.total));
this.local.elevation.gain = this.local.elevation.gain.concat(other.local.elevation.gain.map((gain) => gain + this.global.elevation.gain));
this.local.elevation.loss = this.local.elevation.loss.concat(other.local.elevation.loss.map((loss) => loss + this.global.elevation.loss));
this.elevation.gain += other.elevation.gain;
this.elevation.loss += other.elevation.loss;
this.local.speed = this.local.speed.concat(other.local.speed);
this.local.elevation.smoothed = this.local.elevation.smoothed.concat(other.local.elevation.smoothed);
this.local.slope = this.local.slope.concat(other.local.slope);
this.bounds.southWest.lat = Math.min(this.bounds.southWest.lat, other.bounds.southWest.lat);
this.bounds.southWest.lon = Math.max(this.bounds.southWest.lon, other.bounds.southWest.lon);
this.bounds.northEast.lat = Math.max(this.bounds.northEast.lat, other.bounds.northEast.lat);
this.bounds.northEast.lon = Math.min(this.bounds.northEast.lon, other.bounds.northEast.lon);
this.global.distance.total += other.global.distance.total;
this.global.distance.moving += other.global.distance.moving;
this.global.time.total += other.global.time.total;
this.global.time.moving += other.global.time.moving;
this.global.speed.moving = this.global.distance.moving / (this.global.time.moving / 3600);
this.global.speed.total = this.global.distance.total / (this.global.time.total / 3600);
this.global.elevation.gain += other.global.elevation.gain;
this.global.elevation.loss += other.global.elevation.loss;
this.global.bounds.southWest.lat = Math.min(this.global.bounds.southWest.lat, other.global.bounds.southWest.lat);
this.global.bounds.southWest.lon = Math.max(this.global.bounds.southWest.lon, other.global.bounds.southWest.lon);
this.global.bounds.northEast.lat = Math.max(this.global.bounds.northEast.lat, other.global.bounds.northEast.lat);
this.global.bounds.northEast.lon = Math.min(this.global.bounds.northEast.lon, other.global.bounds.northEast.lon);
}
}
export type TrackPointStatistics = {
distance: number[],
time: number[],
speed: number[],
elevation: {
smoothed: number[],
gain: number[],
loss: number[],
},
slope: number[],
}
const earthRadius = 6371008.8;
export function distance(coord1: Coordinates, coord2: Coordinates): number {
const rad = Math.PI / 180;

View File

@@ -2,7 +2,7 @@
import GPXLayers from '$lib/components/gpx-layer/GPXLayers.svelte';
import ElevationProfile from '$lib/components/ElevationProfile.svelte';
import FileList from '$lib/components/FileList.svelte';
import GPXData from '$lib/components/GPXData.svelte';
import GPXStatistics from '$lib/components/GPXStatistics.svelte';
import Map from '$lib/components/Map.svelte';
import Menu from '$lib/components/Menu.svelte';
import Toolbar from '$lib/components/toolbar/Toolbar.svelte';
@@ -21,7 +21,7 @@
<Toaster richColors />
</div>
<div class="h-48 flex flex-row gap-2 overflow-hidden">
<GPXData />
<GPXStatistics />
<ElevationProfile />
</div>
</div>

View File

@@ -6,7 +6,7 @@
import Chart from 'chart.js/auto';
import mapboxgl from 'mapbox-gl';
import { map, settings, gpxData } from '$lib/stores';
import { map, settings, gpxStatistics } from '$lib/stores';
import { onDestroy, onMount } from 'svelte';
import {
@@ -233,16 +233,16 @@
});
$: if (chart && $settings) {
let data = $gpxData;
let data = $gpxStatistics;
// update data
chart.data.datasets[0] = {
label: $_('quantities.elevation'),
data: data.points.map((point, index) => {
data: data.local.points.map((point, index) => {
return {
x: getConvertedDistance(data.point_statistics.distance[index]),
x: getConvertedDistance(data.local.distance[index]),
y: point.ele ? getConvertedElevation(point.ele) : 0,
slope: data.point_statistics.slope[index],
slope: data.local.slope[index],
surface: point.getSurface(),
coordinates: point.getCoordinates()
};
@@ -253,10 +253,10 @@
};
chart.data.datasets[1] = {
label: datasets.speed.getLabel(),
data: data.points.map((point, index) => {
data: data.local.points.map((point, index) => {
return {
x: getConvertedDistance(data.point_statistics.distance[index]),
y: getConvertedVelocity(data.point_statistics.speed[index])
x: getConvertedDistance(data.local.distance[index]),
y: getConvertedVelocity(data.local.speed[index])
};
}),
normalized: true,
@@ -265,9 +265,9 @@
};
chart.data.datasets[2] = {
label: datasets.hr.getLabel(),
data: data.points.map((point, index) => {
data: data.local.points.map((point, index) => {
return {
x: getConvertedDistance(data.point_statistics.distance[index]),
x: getConvertedDistance(data.local.distance[index]),
y: point.getHeartRate()
};
}),
@@ -277,9 +277,9 @@
};
chart.data.datasets[3] = {
label: datasets.cad.getLabel(),
data: data.points.map((point, index) => {
data: data.local.points.map((point, index) => {
return {
x: getConvertedDistance(data.point_statistics.distance[index]),
x: getConvertedDistance(data.local.distance[index]),
y: point.getCadence()
};
}),
@@ -289,9 +289,9 @@
};
chart.data.datasets[4] = {
label: datasets.atemp.getLabel(),
data: data.points.map((point, index) => {
data: data.local.points.map((point, index) => {
return {
x: getConvertedDistance(data.point_statistics.distance[index]),
x: getConvertedDistance(data.local.distance[index]),
y: getConvertedTemperature(point.getTemperature())
};
}),
@@ -301,9 +301,9 @@
};
chart.data.datasets[5] = {
label: datasets.power.getLabel(),
data: data.points.map((point, index) => {
data: data.local.points.map((point, index) => {
return {
x: getConvertedDistance(data.point_statistics.distance[index]),
x: getConvertedDistance(data.local.distance[index]),
y: point.getPower()
};
}),
@@ -312,7 +312,7 @@
hidden: true
};
chart.options.scales.x['min'] = 0;
chart.options.scales.x['max'] = getConvertedDistance(data.statistics.distance.total);
chart.options.scales.x['max'] = getConvertedDistance(data.global.distance.total);
// update units
for (let [id, dataset] of Object.entries(datasets)) {

View File

@@ -3,17 +3,11 @@
import Tooltip from '$lib/components/Tooltip.svelte';
import WithUnits from '$lib/components/WithUnits.svelte';
import { GPXStatistics } from 'gpx';
import { gpxData, settings } from '$lib/stores';
import { gpxStatistics, settings } from '$lib/stores';
import { MoveDownRight, MoveUpRight, Ruler, Timer, Zap } from 'lucide-svelte';
import { _ } from 'svelte-i18n';
let data: GPXStatistics;
$: data = $gpxData.statistics;
</script>
<Card.Root class="h-full overflow-hidden border-none shadow-none min-w-48 pl-4">
@@ -21,25 +15,25 @@
<Tooltip>
<span slot="data" class="flex flex-row items-center">
<Ruler size="18" class="mr-1" />
<WithUnits value={data.distance.total} type="distance" />
<WithUnits value={$gpxStatistics.global.distance.total} type="distance" />
</span>
<span slot="tooltip">{$_('quantities.distance')}</span>
</Tooltip>
<Tooltip>
<span slot="data" class="flex flex-row items-center">
<MoveUpRight size="18" class="mr-1" />
<WithUnits value={data.elevation.gain} type="elevation" />
<WithUnits value={$gpxStatistics.global.elevation.gain} type="elevation" />
<MoveDownRight size="18" class="mx-1" />
<WithUnits value={data.elevation.loss} type="elevation" />
<WithUnits value={$gpxStatistics.global.elevation.loss} type="elevation" />
</span>
<span slot="tooltip">{$_('quantities.elevation')}</span>
</Tooltip>
<Tooltip>
<span slot="data" class="flex flex-row items-center">
<Zap size="18" class="mr-1" />
<WithUnits value={data.speed.total} type="speed" showUnits={false} />
<WithUnits value={$gpxStatistics.global.speed.total} type="speed" showUnits={false} />
<span class="mx-1">/</span>
<WithUnits value={data.speed.moving} type="speed" />
<WithUnits value={$gpxStatistics.global.speed.moving} type="speed" />
</span>
<span slot="tooltip"
>{$settings.velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace')} ({$_(
@@ -50,9 +44,9 @@
<Tooltip>
<span slot="data" class="flex flex-row items-center">
<Timer size="18" class="mr-1" />
<WithUnits value={data.time.total} type="time" />
<WithUnits value={$gpxStatistics.global.time.total} type="time" />
<span class="mx-1">/</span>
<WithUnits value={data.time.moving} type="time" />
<WithUnits value={$gpxStatistics.global.time.moving} type="time" />
</span>
<span slot="tooltip"
>{$_('quantities.time')} ({$_('quantities.total')} / {$_('quantities.moving')})</span

View File

@@ -1,8 +1,7 @@
import type { GPXFile } from "gpx";
import { map, selectFiles, currentTool, Tool } from "$lib/stores";
import { get, type Readable, type Writable } from "svelte/store";
import { get, type Readable } from "svelte/store";
import mapboxgl from "mapbox-gl";
import type { FreezedObject } from "structurajs";
let defaultWeight = 6;
let defaultOpacity = 1;

View File

@@ -1,12 +1,11 @@
import { writable, get, type Writable } from 'svelte/store';
import mapboxgl from 'mapbox-gl';
import { GPXFile, buildGPX, parseGPX, GPXFiles } from 'gpx';
import { GPXFile, buildGPX, parseGPX, GPXStatistics } from 'gpx';
import { tick } from 'svelte';
import { _ } from 'svelte-i18n';
import type { GPXLayer } from '$lib/components/gpx-layer/GPXLayer';
import { dbUtils, fileObservers } from './db';
import type { FreezedObject } from 'structurajs';
export const map = writable<mapboxgl.Map | null>(null);
@@ -29,18 +28,15 @@ fileObservers.subscribe((files) => { // Update selectedFiles automatically when
}
});
export const gpxData = writable(new GPXFiles([]).getTrackPointsAndStatistics());
const fileStatistics: Map<string, GPXStatistics> = new Map();
export const gpxStatistics: Writable<GPXStatistics> = writable(new GPXStatistics());
function updateGPXData() {
let fileIds: string[] = get(fileOrder).filter((f) => get(selectedFiles).has(f));
let files: GPXFile[] = fileIds
.map((id) => {
let fileObserver = get(fileObservers).get(id);
return fileObserver ? get(fileObserver) : null;
})
.filter((f) => f) as GPXFile[];
let gpxFiles = new GPXFiles(files);
gpxData.set(gpxFiles.getTrackPointsAndStatistics());
let fileIds: string[] = get(fileOrder).filter((f) => fileStatistics.has(f) && get(selectedFiles).has(f));
gpxStatistics.set(fileIds.reduce((stats: GPXStatistics, fileId: string) => {
stats.mergeWith(fileStatistics.get(fileId) ?? new GPXStatistics());
return stats;
}, new GPXStatistics()));
}
let selectedFilesUnsubscribe: Function[] = [];
@@ -49,8 +45,11 @@ selectedFiles.subscribe((selectedFiles) => {
selectedFiles.forEach((fileId) => {
let fileObserver = get(fileObservers).get(fileId);
if (fileObserver) {
let unsubscribe = fileObserver.subscribe(() => {
updateGPXData();
let unsubscribe = fileObserver.subscribe((file) => {
if (file) {
fileStatistics.set(fileId, file.getStatistics());
updateGPXData();
}
});
selectedFilesUnsubscribe.push(unsubscribe);
}
@@ -116,23 +115,23 @@ export async function loadFiles(list: FileList) {
if (file) {
files.push(file);
let fileBounds = file.getStatistics().bounds;
/*let fileBounds = file.getStatistics().bounds;
bounds.extend(fileBounds.southWest);
bounds.extend(fileBounds.northEast);
bounds.extend([fileBounds.southWest.lon, fileBounds.northEast.lat]);
bounds.extend([fileBounds.northEast.lon, fileBounds.southWest.lat]);
bounds.extend([fileBounds.northEast.lon, fileBounds.southWest.lat]);*/
}
}
dbUtils.addMultiple(files);
if (!mapBounds.contains(bounds.getSouthWest()) || !mapBounds.contains(bounds.getNorthEast()) || !mapBounds.contains(bounds.getSouthEast()) || !mapBounds.contains(bounds.getNorthWest())) {
/*if (!mapBounds.contains(bounds.getSouthWest()) || !mapBounds.contains(bounds.getNorthEast()) || !mapBounds.contains(bounds.getSouthEast()) || !mapBounds.contains(bounds.getNorthWest())) {
get(map)?.fitBounds(bounds, {
padding: 80,
linear: true,
easing: () => 1
});
}
}*/
selectFileWhenLoaded(files[0]._data.id);
}
@@ -190,7 +189,7 @@ export function exportAllFiles() {
});
}
export function exportFile(file: FreezedObject<GPXFile>) {
export function exportFile(file: GPXFile) {
let blob = new Blob([buildGPX(file)], { type: 'application/gpx+xml' });
let url = URL.createObjectURL(blob);
let a = document.createElement('a');