mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-09-01 08:12:32 +00:00
change start of loop
This commit is contained in:
@@ -2,7 +2,8 @@
|
|||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import Shortcut from '$lib/components/Shortcut.svelte';
|
import Shortcut from '$lib/components/Shortcut.svelte';
|
||||||
import { Trash2 } from 'lucide-svelte';
|
import { canChangeStart } from './RoutingControls';
|
||||||
|
import { CirclePlay, Trash2 } from 'lucide-svelte';
|
||||||
|
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
|
|
||||||
@@ -12,6 +13,16 @@
|
|||||||
<div bind:this={element} class="hidden">
|
<div bind:this={element} class="hidden">
|
||||||
<Card.Root class="border-none shadow-md text-base">
|
<Card.Root class="border-none shadow-md text-base">
|
||||||
<Card.Content class="flex flex-col p-1">
|
<Card.Content class="flex flex-col p-1">
|
||||||
|
{#if $canChangeStart}
|
||||||
|
<Button
|
||||||
|
class="w-full px-2 py-1 h-6 justify-start"
|
||||||
|
variant="ghost"
|
||||||
|
on:click={() => element.dispatchEvent(new CustomEvent('change-start'))}
|
||||||
|
>
|
||||||
|
<CirclePlay size="16" class="mr-1" />
|
||||||
|
{$_('toolbar.routing.start_loop_here')}
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
<Button
|
<Button
|
||||||
class="w-full px-2 py-1 h-6 justify-start"
|
class="w-full px-2 py-1 h-6 justify-start"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { distance, type Coordinates, TrackPoint, TrackSegment } from "gpx";
|
import { distance, type Coordinates, TrackPoint, TrackSegment } from "gpx";
|
||||||
import { original } from "immer";
|
import { original } from "immer";
|
||||||
import { get, type Readable } from "svelte/store";
|
import { get, writable, type Readable } from "svelte/store";
|
||||||
import mapboxgl from "mapbox-gl";
|
import mapboxgl from "mapbox-gl";
|
||||||
import { route } from "./Routing";
|
import { route } from "./Routing";
|
||||||
|
|
||||||
@@ -13,6 +13,8 @@ import { ListFileItem, ListTrackSegmentItem } from "$lib/components/file-list/Fi
|
|||||||
import { currentTool, Tool } from "$lib/stores";
|
import { currentTool, Tool } from "$lib/stores";
|
||||||
import { resetCursor, setCrosshairCursor, setGrabbingCursor } from "$lib/utils";
|
import { resetCursor, setCrosshairCursor, setGrabbingCursor } from "$lib/utils";
|
||||||
|
|
||||||
|
export const canChangeStart = writable(false);
|
||||||
|
|
||||||
export class RoutingControls {
|
export class RoutingControls {
|
||||||
active: boolean = false;
|
active: boolean = false;
|
||||||
map: mapboxgl.Map;
|
map: mapboxgl.Map;
|
||||||
@@ -182,13 +184,27 @@ export class RoutingControls {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canChangeStart.update(() => {
|
||||||
|
if (anchor.point._data.index === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let segment = anchor.segment;
|
||||||
|
if (distance(segment.trkpt[0].getCoordinates(), segment.trkpt[segment.trkpt.length - 1].getCoordinates()) > 1000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
marker.setPopup(this.popup);
|
marker.setPopup(this.popup);
|
||||||
marker.togglePopup();
|
marker.togglePopup();
|
||||||
|
|
||||||
let deleteThisAnchor = this.getDeleteAnchor(anchor);
|
let deleteThisAnchor = this.getDeleteAnchor(anchor);
|
||||||
this.popupElement.addEventListener('delete', deleteThisAnchor); // Register the delete event for this anchor
|
this.popupElement.addEventListener('delete', deleteThisAnchor); // Register the delete event for this anchor
|
||||||
|
let startLoopAtThisAnchor = this.getStartLoopAtAnchor(anchor);
|
||||||
|
this.popupElement.addEventListener('change-start', startLoopAtThisAnchor); // Register the start loop event for this anchor
|
||||||
this.popup.once('close', () => {
|
this.popup.once('close', () => {
|
||||||
this.popupElement.removeEventListener('delete', deleteThisAnchor);
|
this.popupElement.removeEventListener('delete', deleteThisAnchor);
|
||||||
|
this.popupElement.removeEventListener('change-start', startLoopAtThisAnchor);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -338,6 +354,25 @@ export class RoutingControls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getStartLoopAtAnchor(anchor: Anchor) {
|
||||||
|
return () => this.startLoopAtAnchor(anchor);
|
||||||
|
}
|
||||||
|
|
||||||
|
startLoopAtAnchor(anchor: Anchor) {
|
||||||
|
this.popup.remove();
|
||||||
|
|
||||||
|
let file = get(this.file)?.file;
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let segment = anchor.segment;
|
||||||
|
dbUtils.applyToFile(this.fileId, (file) => {
|
||||||
|
let newFile = file.replaceTrackPoints(anchor.trackIndex, anchor.segmentIndex, segment.trkpt.length, segment.trkpt.length - 1, segment.trkpt.slice(0, anchor.point._data.index));
|
||||||
|
return newFile.replaceTrackPoints(anchor.trackIndex, anchor.segmentIndex, 0, anchor.point._data.index - 1, []);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async appendAnchor(e: mapboxgl.MapMouseEvent) { // Add a new anchor to the end of the last segment
|
async appendAnchor(e: mapboxgl.MapMouseEvent) { // Add a new anchor to the end of the last segment
|
||||||
this.appendAnchorWithCoordinates({
|
this.appendAnchorWithCoordinates({
|
||||||
lat: e.lngLat.lat,
|
lat: e.lngLat.lat,
|
||||||
@@ -372,11 +407,6 @@ export class RoutingControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
routeToStart() {
|
routeToStart() {
|
||||||
let file = get(this.file)?.file;
|
|
||||||
if (!file) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.anchors.length === 0) {
|
if (this.anchors.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -392,11 +422,6 @@ export class RoutingControls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createRoundTrip() {
|
createRoundTrip() {
|
||||||
let file = get(this.file)?.file;
|
|
||||||
if (!file) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.anchors.length === 0) {
|
if (this.anchors.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -60,6 +60,7 @@
|
|||||||
"button": "Round trip",
|
"button": "Round trip",
|
||||||
"tooltip": "Return to the starting point by the same route"
|
"tooltip": "Return to the starting point by the same route"
|
||||||
},
|
},
|
||||||
|
"start_loop_here": "Start loop here",
|
||||||
"help_no_file": "Select a file item to use the routing tool, or create a new file from the menu",
|
"help_no_file": "Select a file item to use the routing tool, or create a new file from the menu",
|
||||||
"help_multiple_files": "Select a single file item to use the routing tool",
|
"help_multiple_files": "Select a single file item to use the routing tool",
|
||||||
"help": "Click on the map to add a new anchor point, or drag existing ones to change the route",
|
"help": "Click on the map to add a new anchor point, or drag existing ones to change the route",
|
||||||
@@ -128,7 +129,7 @@
|
|||||||
"help_merge_contents": "Merging the contents of the selected file items will group all the contents inside the first file item",
|
"help_merge_contents": "Merging the contents of the selected file items will group all the contents inside the first file item",
|
||||||
"help_cannot_merge_contents": "Your selection needs to contain several file items to merge their contents"
|
"help_cannot_merge_contents": "Your selection needs to contain several file items to merge their contents"
|
||||||
},
|
},
|
||||||
"extract_tooltip": "Extract inner tracks or segments",
|
"extract_tooltip": "Extract contents",
|
||||||
"waypoint_tooltip": "Create and edit points of interest",
|
"waypoint_tooltip": "Create and edit points of interest",
|
||||||
"reduce": {
|
"reduce": {
|
||||||
"tooltip": "Reduce the number of GPS points",
|
"tooltip": "Reduce the number of GPS points",
|
||||||
|
Reference in New Issue
Block a user