mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-08-31 15:43:25 +00:00
waypoint popup info
This commit is contained in:
@@ -557,6 +557,14 @@ export class Waypoint {
|
||||
this.attributes = coordinates;
|
||||
}
|
||||
|
||||
getLatitude(): number {
|
||||
return this.attributes.lat;
|
||||
}
|
||||
|
||||
getLongitude(): number {
|
||||
return this.attributes.lon;
|
||||
}
|
||||
|
||||
clone(): Waypoint {
|
||||
return new Waypoint({
|
||||
attributes: cloneJSON(this.attributes),
|
||||
|
@@ -17,38 +17,40 @@
|
||||
const { distanceUnits, velocityUnits, temperatureUnits } = settings;
|
||||
</script>
|
||||
|
||||
{#if type === 'distance'}
|
||||
{#if $distanceUnits === 'metric'}
|
||||
{value.toFixed(2)} {showUnits ? $_('units.kilometers') : ''}
|
||||
{:else}
|
||||
{kilometersToMiles(value).toFixed(2)} {showUnits ? $_('units.miles') : ''}
|
||||
{/if}
|
||||
{:else if type === 'elevation'}
|
||||
{#if $distanceUnits === 'metric'}
|
||||
{value.toFixed(0)} {showUnits ? $_('units.meters') : ''}
|
||||
{:else}
|
||||
{metersToFeet(value).toFixed(0)} {showUnits ? $_('units.feet') : ''}
|
||||
{/if}
|
||||
{:else if type === 'speed'}
|
||||
{#if $distanceUnits === 'metric'}
|
||||
{#if $velocityUnits === 'speed'}
|
||||
{value.toFixed(2)} {showUnits ? $_('units.kilometers_per_hour') : ''}
|
||||
<span class={$$props.class}>
|
||||
{#if type === 'distance'}
|
||||
{#if $distanceUnits === 'metric'}
|
||||
{value.toFixed(2)} {showUnits ? $_('units.kilometers') : ''}
|
||||
{:else}
|
||||
{secondsToHHMMSS(distancePerHourToSecondsPerDistance(value))}
|
||||
{showUnits ? $_('units.minutes_per_kilometer') : ''}
|
||||
{kilometersToMiles(value).toFixed(2)} {showUnits ? $_('units.miles') : ''}
|
||||
{/if}
|
||||
{:else if $velocityUnits === 'speed'}
|
||||
{kilometersToMiles(value).toFixed(2)} {showUnits ? $_('units.miles_per_hour') : ''}
|
||||
{:else}
|
||||
{secondsToHHMMSS(distancePerHourToSecondsPerDistance(kilometersToMiles(value)))}
|
||||
{showUnits ? $_('units.minutes_per_mile') : ''}
|
||||
{:else if type === 'elevation'}
|
||||
{#if $distanceUnits === 'metric'}
|
||||
{value.toFixed(0)} {showUnits ? $_('units.meters') : ''}
|
||||
{:else}
|
||||
{metersToFeet(value).toFixed(0)} {showUnits ? $_('units.feet') : ''}
|
||||
{/if}
|
||||
{:else if type === 'speed'}
|
||||
{#if $distanceUnits === 'metric'}
|
||||
{#if $velocityUnits === 'speed'}
|
||||
{value.toFixed(2)} {showUnits ? $_('units.kilometers_per_hour') : ''}
|
||||
{:else}
|
||||
{secondsToHHMMSS(distancePerHourToSecondsPerDistance(value))}
|
||||
{showUnits ? $_('units.minutes_per_kilometer') : ''}
|
||||
{/if}
|
||||
{:else if $velocityUnits === 'speed'}
|
||||
{kilometersToMiles(value).toFixed(2)} {showUnits ? $_('units.miles_per_hour') : ''}
|
||||
{:else}
|
||||
{secondsToHHMMSS(distancePerHourToSecondsPerDistance(kilometersToMiles(value)))}
|
||||
{showUnits ? $_('units.minutes_per_mile') : ''}
|
||||
{/if}
|
||||
{:else if type === 'temperature'}
|
||||
{#if $temperatureUnits === 'celsius'}
|
||||
{value} {showUnits ? $_('units.celsius') : ''}
|
||||
{:else}
|
||||
{celsiusToFahrenheit(value)} {showUnits ? $_('units.fahrenheit') : ''}
|
||||
{/if}
|
||||
{:else if type === 'time'}
|
||||
{secondsToHHMMSS(value)}
|
||||
{/if}
|
||||
{:else if type === 'temperature'}
|
||||
{#if $temperatureUnits === 'celsius'}
|
||||
{value} {showUnits ? $_('units.celsius') : ''}
|
||||
{:else}
|
||||
{celsiusToFahrenheit(value)} {showUnits ? $_('units.fahrenheit') : ''}
|
||||
{/if}
|
||||
{:else if type === 'time'}
|
||||
{secondsToHHMMSS(value)}
|
||||
{/if}
|
||||
</span>
|
||||
|
@@ -2,6 +2,7 @@ import { map, selectFiles, currentTool, Tool } from "$lib/stores";
|
||||
import { settings, type GPXFileWithStatistics } from "$lib/db";
|
||||
import { get, type Readable } from "svelte/store";
|
||||
import mapboxgl from "mapbox-gl";
|
||||
import { currentWaypoint, waypointPopup } from "./WaypointPopup";
|
||||
|
||||
let defaultWeight = 6;
|
||||
let defaultOpacity = 1;
|
||||
@@ -43,21 +44,17 @@ export class GPXLayer {
|
||||
fileId: string;
|
||||
file: Readable<GPXFileWithStatistics | undefined>;
|
||||
layerColor: string;
|
||||
popup: mapboxgl.Popup;
|
||||
popupElement: HTMLElement;
|
||||
markers: mapboxgl.Marker[] = [];
|
||||
unsubscribe: Function[] = [];
|
||||
|
||||
updateBinded: () => void = this.update.bind(this);
|
||||
selectOnClickBinded: (e: any) => void = this.selectOnClick.bind(this);
|
||||
|
||||
constructor(map: mapboxgl.Map, fileId: string, file: Readable<GPXFileWithStatistics | undefined>, popup: mapboxgl.Popup, popupElement: HTMLElement) {
|
||||
constructor(map: mapboxgl.Map, fileId: string, file: Readable<GPXFileWithStatistics | undefined>) {
|
||||
this.map = map;
|
||||
this.fileId = fileId;
|
||||
this.file = file;
|
||||
this.layerColor = getColor();
|
||||
this.popup = popup;
|
||||
this.popupElement = popupElement;
|
||||
this.unsubscribe.push(file.subscribe(this.updateBinded));
|
||||
this.unsubscribe.push(directionMarkers.subscribe(this.updateBinded));
|
||||
this.unsubscribe.push(distanceMarkers.subscribe(this.updateBinded));
|
||||
@@ -182,11 +179,15 @@ export class GPXLayer {
|
||||
this.markers[markerIndex].setLngLat(waypoint.getCoordinates());
|
||||
} else {
|
||||
let marker = new mapboxgl.Marker().setLngLat(waypoint.getCoordinates());
|
||||
marker.getElement().addEventListener('click', (e) => {
|
||||
marker.setPopup(this.popup);
|
||||
marker.getElement().addEventListener('mouseover', (e) => {
|
||||
currentWaypoint.set(waypoint);
|
||||
marker.setPopup(waypointPopup);
|
||||
marker.togglePopup();
|
||||
e.stopPropagation();
|
||||
});
|
||||
marker.getElement().addEventListener('mouseout', () => {
|
||||
marker.togglePopup();
|
||||
});
|
||||
|
||||
this.markers.push(marker);
|
||||
}
|
||||
|
@@ -2,14 +2,9 @@
|
||||
import { map, selectedFiles, gpxLayers } from '$lib/stores';
|
||||
import { GPXLayer } from './GPXLayer';
|
||||
import { get } from 'svelte/store';
|
||||
import { onMount } from 'svelte';
|
||||
import mapboxgl from 'mapbox-gl';
|
||||
import WaypointPopup from './WaypointPopup.svelte';
|
||||
import { fileObservers } from '$lib/db';
|
||||
|
||||
let popupElement: HTMLElement;
|
||||
let popup: mapboxgl.Popup | null = null;
|
||||
|
||||
$: if ($map && $fileObservers) {
|
||||
gpxLayers.update(($layers) => {
|
||||
// remove layers for deleted files
|
||||
@@ -22,7 +17,7 @@
|
||||
// add layers for new files
|
||||
$fileObservers.forEach((file, fileId) => {
|
||||
if (!$layers.has(fileId)) {
|
||||
$layers.set(fileId, new GPXLayer(get(map), fileId, file, popup, popupElement));
|
||||
$layers.set(fileId, new GPXLayer(get(map), fileId, file));
|
||||
}
|
||||
});
|
||||
return $layers;
|
||||
@@ -34,15 +29,6 @@
|
||||
$gpxLayers.get(fileId)?.moveToFront();
|
||||
}
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
popup = new mapboxgl.Popup({
|
||||
closeButton: false,
|
||||
maxWidth: undefined
|
||||
});
|
||||
popup.setDOMContent(popupElement);
|
||||
popupElement.classList.remove('hidden');
|
||||
});
|
||||
</script>
|
||||
|
||||
<WaypointPopup bind:element={popupElement} />
|
||||
<WaypointPopup />
|
||||
|
@@ -1,13 +1,43 @@
|
||||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { waypointPopup, currentWaypoint } from './WaypointPopup';
|
||||
import WithUnits from '$lib/components/WithUnits.svelte';
|
||||
import { Dot } from 'lucide-svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
export let element: HTMLElement;
|
||||
let popupElement: HTMLDivElement;
|
||||
|
||||
onMount(() => {
|
||||
waypointPopup.setDOMContent(popupElement);
|
||||
popupElement.classList.remove('hidden');
|
||||
});
|
||||
</script>
|
||||
|
||||
<div bind:this={element} class="hidden">
|
||||
<Card.Root class="border-none shadow-md text-base">
|
||||
<Card.Content class="flex flex-col p-1">Waypoint info (TODO)</Card.Content>
|
||||
</Card.Root>
|
||||
<div bind:this={popupElement} class="hidden">
|
||||
{#if $currentWaypoint}
|
||||
<Card.Root class="border-none shadow-md text-base max-w-72 p-2">
|
||||
<Card.Header class="p-0">
|
||||
<Card.Title class="text-md">{$currentWaypoint.name}</Card.Title>
|
||||
</Card.Header>
|
||||
<Card.Content class="flex flex-col p-0 text-sm">
|
||||
<div class="flex flex-row items-center text-muted-foreground">
|
||||
{$currentWaypoint.getLatitude().toFixed(6)}° {$currentWaypoint
|
||||
.getLongitude()
|
||||
.toFixed(6)}°
|
||||
{#if $currentWaypoint.ele !== undefined}
|
||||
<Dot size="16" />
|
||||
<WithUnits value={$currentWaypoint.ele} type="elevation" />
|
||||
{/if}
|
||||
</div>
|
||||
{#if $currentWaypoint.desc}
|
||||
<span>{$currentWaypoint.desc}</span>
|
||||
{/if}
|
||||
{#if $currentWaypoint.cmt}
|
||||
<span>{$currentWaypoint.cmt}</span>
|
||||
{/if}
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
{/if}
|
||||
</div>
|
||||
|
10
website/src/lib/components/gpx-layer/WaypointPopup.ts
Normal file
10
website/src/lib/components/gpx-layer/WaypointPopup.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { Waypoint } from "gpx";
|
||||
import mapboxgl from "mapbox-gl";
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export const currentWaypoint = writable<Waypoint | null>(null);
|
||||
|
||||
export const waypointPopup = new mapboxgl.Popup({
|
||||
closeButton: false,
|
||||
maxWidth: undefined
|
||||
});
|
Reference in New Issue
Block a user