diff --git a/website/src/lib/components/embedding/Embedding.svelte b/website/src/lib/components/embedding/Embedding.svelte index 3bfff428..47c6409d 100644 --- a/website/src/lib/components/embedding/Embedding.svelte +++ b/website/src/lib/components/embedding/Embedding.svelte @@ -3,11 +3,18 @@ import ElevationProfile from '$lib/components/ElevationProfile.svelte'; import FileList from '$lib/components/file-list/FileList.svelte'; import GPXStatistics from '$lib/components/GPXStatistics.svelte'; - import MapComponent from '$lib/components/Map.svelte'; + import Map from '$lib/components/Map.svelte'; import LayerControl from '$lib/components/layer-control/LayerControl.svelte'; import OpenIn from '$lib/components/embedding/OpenIn.svelte'; - import { gpxStatistics, slicedGPXStatistics, embedding, loadFile, map } from '$lib/stores'; + import { + gpxStatistics, + slicedGPXStatistics, + embedding, + loadFile, + map, + updateGPXData + } from '$lib/stores'; import { onDestroy, onMount } from 'svelte'; import { fileObservers, settings, GPXStatisticsTree } from '$lib/db'; import { readable } from 'svelte/store'; @@ -167,6 +174,10 @@ applyOptions(); } + $: if ($fileOrder) { + updateGPXData(); + } + onDestroy(() => { if ($distanceMarkers !== prevSettings.distanceMarkers) { $distanceMarkers = prevSettings.distanceMarkers; @@ -194,7 +205,7 @@
- void = this.update.bind(this); + unsubscribes: (() => void)[] = []; constructor(map: mapboxgl.Map) { this.map = map; - gpxStatistics.subscribe(this.updateBinded); - distanceMarkers.subscribe(this.updateBinded); - distanceUnits.subscribe(this.updateBinded); + this.unsubscribes.push(gpxStatistics.subscribe(this.updateBinded)); + this.unsubscribes.push(distanceMarkers.subscribe(this.updateBinded)); + this.unsubscribes.push(distanceUnits.subscribe(this.updateBinded)); this.map.on('style.load', this.updateBinded); } @@ -61,6 +62,10 @@ export class DistanceMarkers { } } + remove() { + this.unsubscribes.forEach(unsubscribe => unsubscribe()); + } + getDistanceMarkersGeoJSON(): GeoJSON.FeatureCollection { let statistics = get(gpxStatistics); diff --git a/website/src/lib/components/gpx-layer/GPXLayer.ts b/website/src/lib/components/gpx-layer/GPXLayer.ts index 9649410d..a8a40c95 100644 --- a/website/src/lib/components/gpx-layer/GPXLayer.ts +++ b/website/src/lib/components/gpx-layer/GPXLayer.ts @@ -1,4 +1,4 @@ -import { currentTool, Tool } from "$lib/stores"; +import { currentTool, map, Tool } from "$lib/stores"; import { settings, type GPXFileWithStatistics, dbUtils } from "$lib/db"; import { get, type Readable } from "svelte/store"; import mapboxgl from "mapbox-gl"; @@ -259,20 +259,28 @@ export class GPXLayer { }); } - remove() { - this.map.off('click', this.fileId, this.layerOnClickBinded); - this.map.off('mouseenter', this.fileId, this.layerOnMouseEnterBinded); - this.map.off('mouseleave', this.fileId, this.layerOnMouseLeaveBinded); - this.map.off('style.load', this.updateBinded); + updateMap(map: mapboxgl.Map) { + this.map = map; + this.map.on('style.load', this.updateBinded); + this.update(); + } - if (this.map.getLayer(this.fileId + '-direction')) { - this.map.removeLayer(this.fileId + '-direction'); - } - if (this.map.getLayer(this.fileId)) { - this.map.removeLayer(this.fileId); - } - if (this.map.getSource(this.fileId)) { - this.map.removeSource(this.fileId); + remove() { + if (get(map)) { + this.map.off('click', this.fileId, this.layerOnClickBinded); + this.map.off('mouseenter', this.fileId, this.layerOnMouseEnterBinded); + this.map.off('mouseleave', this.fileId, this.layerOnMouseLeaveBinded); + this.map.off('style.load', this.updateBinded); + + if (this.map.getLayer(this.fileId + '-direction')) { + this.map.removeLayer(this.fileId + '-direction'); + } + if (this.map.getLayer(this.fileId)) { + this.map.removeLayer(this.fileId); + } + if (this.map.getSource(this.fileId)) { + this.map.removeSource(this.fileId); + } } this.markers.forEach((marker) => { diff --git a/website/src/lib/components/gpx-layer/GPXLayers.svelte b/website/src/lib/components/gpx-layer/GPXLayers.svelte index 84dc0678..b18cbf86 100644 --- a/website/src/lib/components/gpx-layer/GPXLayers.svelte +++ b/website/src/lib/components/gpx-layer/GPXLayers.svelte @@ -5,9 +5,10 @@ import { fileObservers } from '$lib/db'; import { DistanceMarkers } from './DistanceMarkers'; import { StartEndMarkers } from './StartEndMarkers'; + import { onDestroy } from 'svelte'; - let distanceMarkers: DistanceMarkers; - let startEndMarkers: StartEndMarkers; + let distanceMarkers: DistanceMarkers | undefined = undefined; + let startEndMarkers: StartEndMarkers | undefined = undefined; $: if ($map && $fileObservers) { // remove layers for deleted files @@ -15,6 +16,8 @@ if (!$fileObservers.has(fileId)) { layer.remove(); gpxLayers.delete(fileId); + } else if ($map !== layer.map) { + layer.updateMap($map); } }); // add layers for new files @@ -26,9 +29,30 @@ } $: if ($map) { + if (distanceMarkers) { + distanceMarkers.remove(); + } + if (startEndMarkers) { + startEndMarkers.remove(); + } distanceMarkers = new DistanceMarkers($map); startEndMarkers = new StartEndMarkers($map); } + + onDestroy(() => { + gpxLayers.forEach((layer) => layer.remove()); + gpxLayers.clear(); + + if (distanceMarkers) { + distanceMarkers.remove(); + distanceMarkers = undefined; + } + + if (startEndMarkers) { + startEndMarkers.remove(); + startEndMarkers = undefined; + } + }); diff --git a/website/src/lib/components/gpx-layer/StartEndMarkers.ts b/website/src/lib/components/gpx-layer/StartEndMarkers.ts index eec81605..41936f79 100644 --- a/website/src/lib/components/gpx-layer/StartEndMarkers.ts +++ b/website/src/lib/components/gpx-layer/StartEndMarkers.ts @@ -7,6 +7,7 @@ export class StartEndMarkers { start: mapboxgl.Marker; end: mapboxgl.Marker; updateBinded: () => void = this.update.bind(this); + unsubscribes: (() => void)[] = []; constructor(map: mapboxgl.Map) { this.map = map; @@ -20,9 +21,9 @@ export class StartEndMarkers { this.start = new mapboxgl.Marker({ element: startElement }); this.end = new mapboxgl.Marker({ element: endElement }); - gpxStatistics.subscribe(this.updateBinded); - slicedGPXStatistics.subscribe(this.updateBinded); - currentTool.subscribe(this.updateBinded); + this.unsubscribes.push(gpxStatistics.subscribe(this.updateBinded)); + this.unsubscribes.push(slicedGPXStatistics.subscribe(this.updateBinded)); + this.unsubscribes.push(currentTool.subscribe(this.updateBinded)); } update() { @@ -36,4 +37,11 @@ export class StartEndMarkers { this.end.remove(); } } + + remove() { + this.unsubscribes.forEach(unsubscribe => unsubscribe()); + + this.start.remove(); + this.end.remove(); + } } \ No newline at end of file diff --git a/website/src/lib/components/toolbar/tools/routing/Routing.svelte b/website/src/lib/components/toolbar/tools/routing/Routing.svelte index 7de21cbf..a9a6e698 100644 --- a/website/src/lib/components/toolbar/tools/routing/Routing.svelte +++ b/website/src/lib/components/toolbar/tools/routing/Routing.svelte @@ -54,15 +54,14 @@ if (selectedItem && selectedItem.getFileId() === fileId) { selectedItem = null; } + } else if ($map !== controls.map) { + controls.updateMap($map); } }); // add controls for new files $fileObservers.forEach((file, fileId) => { if (!routingControls.has(fileId)) { - routingControls.set( - fileId, - new RoutingControls(get(map), fileId, file, popup, popupElement) - ); + routingControls.set(fileId, new RoutingControls($map, fileId, file, popup, popupElement)); } }); } @@ -92,6 +91,9 @@ onDestroy(() => { $map?.off('click', createFileWithPoint); + + routingControls.forEach((controls) => controls.destroy()); + routingControls.clear(); }); diff --git a/website/src/lib/components/toolbar/tools/routing/RoutingControls.ts b/website/src/lib/components/toolbar/tools/routing/RoutingControls.ts index 8137dc1b..8ac1d835 100644 --- a/website/src/lib/components/toolbar/tools/routing/RoutingControls.ts +++ b/website/src/lib/components/toolbar/tools/routing/RoutingControls.ts @@ -135,6 +135,10 @@ export class RoutingControls { this.fileUnsubscribe(); } + updateMap(map: mapboxgl.Map) { + this.map = map; + } + createAnchor(point: TrackPoint, segment: TrackSegment, trackIndex: number, segmentIndex: number): AnchorWithMarker { let element = document.createElement('div'); element.className = `h-3 w-3 rounded-full bg-white border-2 border-black cursor-pointer`; diff --git a/website/src/lib/stores.ts b/website/src/lib/stores.ts index 4349d24b..6b1b9f1a 100644 --- a/website/src/lib/stores.ts +++ b/website/src/lib/stores.ts @@ -20,7 +20,7 @@ export const selectFiles = writable<{ [key: string]: (fileId?: string) => void } export const gpxStatistics: Writable = writable(new GPXStatistics()); export const slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined> = writable(undefined); -function updateGPXData() { +export function updateGPXData() { let statistics = new GPXStatistics(); applyToOrderedSelectedItemsFromFile((fileId, level, items) => { let stats = getStatistics(fileId);