mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-11-04 13:31:13 +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