mirror of
				https://github.com/gpxstudio/gpx.studio.git
				synced 2025-11-04 05:21:09 +00:00 
			
		
		
		
	start/end & distance markers
This commit is contained in:
		@@ -1,41 +1,33 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
    import { gpxLayers } from '$lib/components/map/gpx-layer/gpx-layers';
 | 
			
		||||
    import { onMount } from 'svelte';
 | 
			
		||||
    import { onDestroy, onMount } from 'svelte';
 | 
			
		||||
    // import { map, gpxLayers } from '$lib/stores';
 | 
			
		||||
    // import { GPXLayer } from './gpx-layer';
 | 
			
		||||
    // import { DistanceMarkers } from './DistanceMarkers';
 | 
			
		||||
    // import { StartEndMarkers } from './StartEndMarkers';
 | 
			
		||||
    import { DistanceMarkers } from '$lib/components/map/gpx-layer/distance-markers';
 | 
			
		||||
    import { StartEndMarkers } from '$lib/components/map/gpx-layer/start-end-markers';
 | 
			
		||||
    // import { onDestroy } from 'svelte';
 | 
			
		||||
    // import { createPopups, removePopups } from './GPXLayerPopup';
 | 
			
		||||
 | 
			
		||||
    // let distanceMarkers = $derived(map.current ? new DistanceMarkers(map.current) : undefined);
 | 
			
		||||
    // let startEndMarkers = $derived(map.current ? new StartEndMarkers(map.current) : undefined);
 | 
			
		||||
    let distanceMarkers: DistanceMarkers;
 | 
			
		||||
    let startEndMarkers: StartEndMarkers;
 | 
			
		||||
 | 
			
		||||
    // $: if ($map) {
 | 
			
		||||
    //     if (distanceMarkers) {
 | 
			
		||||
    //         distanceMarkers.remove();
 | 
			
		||||
    //     }
 | 
			
		||||
    //     if (startEndMarkers) {
 | 
			
		||||
    //         startEndMarkers.remove();
 | 
			
		||||
    //     }
 | 
			
		||||
    //     createPopups($map);
 | 
			
		||||
    //     distanceMarkers = new DistanceMarkers($map);
 | 
			
		||||
    //     startEndMarkers = new StartEndMarkers($map);
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // onDestroy(() => {
 | 
			
		||||
    //     removePopups();
 | 
			
		||||
    //     if (distanceMarkers) {
 | 
			
		||||
    //         distanceMarkers.remove();
 | 
			
		||||
    //         distanceMarkers = undefined;
 | 
			
		||||
    //     }
 | 
			
		||||
    //     if (startEndMarkers) {
 | 
			
		||||
    //         startEndMarkers.remove();
 | 
			
		||||
    //         startEndMarkers = undefined;
 | 
			
		||||
    //     }
 | 
			
		||||
    // });
 | 
			
		||||
 | 
			
		||||
    onMount(() => {
 | 
			
		||||
        gpxLayers.init();
 | 
			
		||||
        startEndMarkers = new StartEndMarkers();
 | 
			
		||||
        distanceMarkers = new DistanceMarkers();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    onDestroy(() => {
 | 
			
		||||
        // removePopups();
 | 
			
		||||
        if (startEndMarkers) {
 | 
			
		||||
            startEndMarkers.remove();
 | 
			
		||||
        }
 | 
			
		||||
        if (distanceMarkers) {
 | 
			
		||||
            distanceMarkers.remove();
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
import { settings } from '$lib/logic/settings';
 | 
			
		||||
import { gpxStatistics } from '$lib/logic/statistics';
 | 
			
		||||
import { getConvertedDistanceToKilometers } from '$lib/units';
 | 
			
		||||
import type { GeoJSONSource } from 'mapbox-gl';
 | 
			
		||||
import { get } from 'svelte/store';
 | 
			
		||||
import { map } from '$lib/components/map/map';
 | 
			
		||||
 | 
			
		||||
const { distanceMarkers, distanceUnits } = settings;
 | 
			
		||||
 | 
			
		||||
@@ -14,35 +17,40 @@ const stops = [
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export class DistanceMarkers {
 | 
			
		||||
    map: mapboxgl.Map;
 | 
			
		||||
    updateBinded: () => void = this.update.bind(this);
 | 
			
		||||
    unsubscribes: (() => void)[] = [];
 | 
			
		||||
 | 
			
		||||
    constructor(map: mapboxgl.Map) {
 | 
			
		||||
        this.map = map;
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        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.import.load', this.updateBinded);
 | 
			
		||||
        this.unsubscribes.push(
 | 
			
		||||
            map.subscribe((map_) => {
 | 
			
		||||
                if (map_) {
 | 
			
		||||
                    map_.on('style.import.load', this.updateBinded);
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update() {
 | 
			
		||||
        const map_ = get(map);
 | 
			
		||||
        if (!map_) return;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            if (get(distanceMarkers)) {
 | 
			
		||||
                let distanceSource: GeoJSONSource | undefined =
 | 
			
		||||
                    this.map.getSource('distance-markers');
 | 
			
		||||
                let distanceSource: GeoJSONSource | undefined = map_.getSource('distance-markers');
 | 
			
		||||
                if (distanceSource) {
 | 
			
		||||
                    distanceSource.setData(this.getDistanceMarkersGeoJSON());
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.map.addSource('distance-markers', {
 | 
			
		||||
                    map_.addSource('distance-markers', {
 | 
			
		||||
                        type: 'geojson',
 | 
			
		||||
                        data: this.getDistanceMarkersGeoJSON(),
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
                stops.forEach(([d, minzoom, maxzoom]) => {
 | 
			
		||||
                    if (!this.map.getLayer(`distance-markers-${d}`)) {
 | 
			
		||||
                        this.map.addLayer({
 | 
			
		||||
                    if (!map_.getLayer(`distance-markers-${d}`)) {
 | 
			
		||||
                        map_.addLayer({
 | 
			
		||||
                            id: `distance-markers-${d}`,
 | 
			
		||||
                            type: 'symbol',
 | 
			
		||||
                            source: 'distance-markers',
 | 
			
		||||
@@ -68,13 +76,13 @@ export class DistanceMarkers {
 | 
			
		||||
                            },
 | 
			
		||||
                        });
 | 
			
		||||
                    } else {
 | 
			
		||||
                        this.map.moveLayer(`distance-markers-${d}`);
 | 
			
		||||
                        map_.moveLayer(`distance-markers-${d}`);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            } else {
 | 
			
		||||
                stops.forEach(([d]) => {
 | 
			
		||||
                    if (this.map.getLayer(`distance-markers-${d}`)) {
 | 
			
		||||
                        this.map.removeLayer(`distance-markers-${d}`);
 | 
			
		||||
                    if (map_.getLayer(`distance-markers-${d}`)) {
 | 
			
		||||
                        map_.removeLayer(`distance-markers-${d}`);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
@@ -96,7 +104,7 @@ export class DistanceMarkers {
 | 
			
		||||
        for (let i = 0; i < statistics.local.distance.total.length; i++) {
 | 
			
		||||
            if (
 | 
			
		||||
                statistics.local.distance.total[i] >=
 | 
			
		||||
                currentTargetDistance * (get(distanceUnits) === 'metric' ? 1 : 1.60934)
 | 
			
		||||
                getConvertedDistanceToKilometers(currentTargetDistance)
 | 
			
		||||
            ) {
 | 
			
		||||
                let distance = currentTargetDistance.toFixed(0);
 | 
			
		||||
                let [level, minzoom] = stops.find(([d]) => currentTargetDistance % d === 0) ?? [
 | 
			
		||||
@@ -1,17 +1,16 @@
 | 
			
		||||
import { gpxStatistics, slicedGPXStatistics, currentTool, Tool } from '$lib/stores';
 | 
			
		||||
import { currentTool, Tool } from '$lib/components/toolbar/tools';
 | 
			
		||||
import { gpxStatistics, slicedGPXStatistics } from '$lib/logic/statistics';
 | 
			
		||||
import mapboxgl from 'mapbox-gl';
 | 
			
		||||
import { get } from 'svelte/store';
 | 
			
		||||
import { map } from '$lib/components/map/map';
 | 
			
		||||
 | 
			
		||||
export class StartEndMarkers {
 | 
			
		||||
    map: mapboxgl.Map;
 | 
			
		||||
    start: mapboxgl.Marker;
 | 
			
		||||
    end: mapboxgl.Marker;
 | 
			
		||||
    updateBinded: () => void = this.update.bind(this);
 | 
			
		||||
    unsubscribes: (() => void)[] = [];
 | 
			
		||||
 | 
			
		||||
    constructor(map: mapboxgl.Map) {
 | 
			
		||||
        this.map = map;
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
        let startElement = document.createElement('div');
 | 
			
		||||
        let endElement = document.createElement('div');
 | 
			
		||||
        startElement.className = `h-4 w-4 rounded-full bg-green-500 border-2 border-white`;
 | 
			
		||||
@@ -28,15 +27,18 @@ export class StartEndMarkers {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    update() {
 | 
			
		||||
        let tool = get(currentTool);
 | 
			
		||||
        let statistics = get(slicedGPXStatistics)?.[0] ?? get(gpxStatistics);
 | 
			
		||||
        const map_ = get(map);
 | 
			
		||||
        if (!map_) return;
 | 
			
		||||
 | 
			
		||||
        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.start.setLngLat(statistics.local.points[0].getCoordinates()).addTo(map_);
 | 
			
		||||
            this.end
 | 
			
		||||
                .setLngLat(
 | 
			
		||||
                    statistics.local.points[statistics.local.points.length - 1].getCoordinates()
 | 
			
		||||
                )
 | 
			
		||||
                .addTo(this.map);
 | 
			
		||||
                .addTo(map_);
 | 
			
		||||
        } else {
 | 
			
		||||
            this.start.remove();
 | 
			
		||||
            this.end.remove();
 | 
			
		||||
@@ -178,6 +178,20 @@ export function getConvertedDistance(value: number, targetDistanceUnits = get(di
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getConvertedDistanceToKilometers(
 | 
			
		||||
    value: number,
 | 
			
		||||
    sourceDistanceUnits = get(distanceUnits)
 | 
			
		||||
) {
 | 
			
		||||
    switch (sourceDistanceUnits) {
 | 
			
		||||
        case 'metric':
 | 
			
		||||
            return value;
 | 
			
		||||
        case 'imperial':
 | 
			
		||||
            return milesToKilometers(value);
 | 
			
		||||
        case 'nautical':
 | 
			
		||||
            return nauticalMilesToKilometers(value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getConvertedElevation(value: number, targetDistanceUnits = get(distanceUnits)) {
 | 
			
		||||
    switch (targetDistanceUnits) {
 | 
			
		||||
        case 'metric':
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user