clean tool

This commit is contained in:
vcoppe
2026-10-04 20:38:46 +02:00
parent c04367dd86
commit c6bd5b06e8
4 changed files with 422 additions and 69 deletions
@@ -17,8 +17,7 @@
import { Trash2 } from '@lucide/svelte';
import { map } from '$lib/components/map/map';
import type { GeoJSONSource } from 'maplibre-gl';
import { selection } from '$lib/logic/selection';
import { fileActions } from '$lib/logic/file-actions';
import { engine } from '$lib/engine';
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
import { ANCHOR_LAYER_KEY } from '$lib/components/map/style';
@@ -130,7 +129,8 @@
}
});
let validSelection = $derived($selection.size > 0);
const selection = engine.selection;
let validSelection = $derived($selection.type !== 'empty');
</script>
<div class="flex flex-col gap-3 w-full max-w-80 items-center {props.class ?? ''}">
@@ -163,17 +163,13 @@
class="w-full"
disabled={!validSelection || rectangleCoordinates.length != 2}
onclick={() => {
fileActions.cleanSelection(
[
{
lat: Math.min(rectangleCoordinates[0].lat, rectangleCoordinates[1].lat),
lon: Math.min(rectangleCoordinates[0].lng, rectangleCoordinates[1].lng),
},
{
lat: Math.max(rectangleCoordinates[0].lat, rectangleCoordinates[1].lat),
lon: Math.max(rectangleCoordinates[0].lng, rectangleCoordinates[1].lng),
},
],
engine.clean(
{
west: Math.min(rectangleCoordinates[0].lng, rectangleCoordinates[1].lng),
south: Math.min(rectangleCoordinates[0].lat, rectangleCoordinates[1].lat),
east: Math.max(rectangleCoordinates[0].lng, rectangleCoordinates[1].lng),
north: Math.max(rectangleCoordinates[0].lat, rectangleCoordinates[1].lat),
},
cleanType === CleanType.INSIDE,
deleteTrackpoints,
deleteWaypoints
+23
View File
@@ -494,6 +494,29 @@ class Engine {
return this.run((w) => w.delete_waypoint(fileId, waypointId));
}
/**
* Removes the trackpoints and/or waypoints of the selection inside (or outside) a rectangle.
* Resolves to `false` when nothing was removed.
*/
clean(
bounds: { west: number; south: number; east: number; north: number },
inside: boolean,
trackpoints: boolean,
waypoints: boolean
) {
return this.run((w) =>
w.clean(
bounds.west,
bounds.south,
bounds.east,
bounds.north,
inside ? w.CleanType.Inside : w.CleanType.Outside,
trackpoints,
waypoints
)
);
}
/** A trackpoint of a segment, `undefined` if it does not exist. */
trackpoint(fileId: string, segmentId: string, index: number): TrackpointDetails | undefined {
return this.wasm?.trackpoint(fileId, segmentId, index);
-51
View File
@@ -570,57 +570,6 @@ export const fileActions = {
}
});
},
cleanSelection: (
bounds: [Coordinates, Coordinates],
inside: boolean,
deleteTrackPoints: boolean,
deleteWaypoints: boolean
) => {
if (get(selection).size === 0) {
return;
}
fileActionManager.applyGlobal((draft) => {
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let file = draft.get(fileId);
if (file) {
if (level === ListLevel.FILE) {
file.clean(bounds, inside, deleteTrackPoints, deleteWaypoints);
} else if (level === ListLevel.TRACK) {
let trackIndices = items.map((item) =>
(item as ListTrackItem).getTrackIndex()
);
file.clean(
bounds,
inside,
deleteTrackPoints,
deleteWaypoints,
trackIndices
);
} else if (level === ListLevel.SEGMENT) {
let trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
let segmentIndices = items.map((item) =>
(item as ListTrackSegmentItem).getSegmentIndex()
);
file.clean(
bounds,
inside,
deleteTrackPoints,
deleteWaypoints,
trackIndices,
segmentIndices
);
} else if (level === ListLevel.WAYPOINTS) {
file.clean(bounds, inside, false, deleteWaypoints);
} else if (level === ListLevel.WAYPOINT) {
let waypointIndices = items.map((item) =>
(item as ListWaypointItem).getWaypointIndex()
);
file.clean(bounds, inside, false, deleteWaypoints, [], [], waypointIndices);
}
}
});
});
},
reduce: (itemsAndPoints: Map<ListItem, TrackPoint[]>) => {
if (itemsAndPoints.size === 0) {
return;