waypoint editing while drawing a route (#1060)

* waypoint editing while drawing a route

* fix waypoint click while drawing

---------

Co-authored-by: Christian Beutel <>
This commit is contained in:
slothful-vassal
2026-06-16 19:55:46 +02:00
committed by GitHub
parent c04a719ca6
commit 6baeafe755
6 changed files with 115 additions and 48 deletions

View File

@@ -37,6 +37,7 @@
markers?: M.Marker[];
map?: M.Map | null;
drawing?: boolean;
displayWaypoints?: boolean;
showElevation?: boolean;
showInfoPopup?: boolean;
showGrid?: boolean;
@@ -65,6 +66,7 @@
onmoveend?: (map: M.Map) => void;
onzoom?: (map: M.Map) => void;
onclick?: (event: M.MapMouseEvent & Object) => void;
oncontextmenu?: (event: M.MapMouseEvent & Object) => void;
onUnclusteredClick?: (
event: M.MapMouseEvent & Object,
trail: Trail,
@@ -81,6 +83,7 @@
markers = $bindable([]),
map = $bindable(),
drawing = false,
displayWaypoints = true,
showElevation = true,
showInfoPopup = false,
showGrid = false,
@@ -101,6 +104,7 @@
onmoveend,
onzoom,
onclick,
oncontextmenu,
onUnclusteredClick,
oninit,
autoGeolocateOnDrawing = false,
@@ -190,8 +194,9 @@
});
$effect(() => {
waypoints;
displayWaypoints;
untrack(() => {
showWaypoints();
syncWaypointMarkers();
refreshElevationProfile();
});
});
@@ -668,7 +673,7 @@
if (showElevation) {
epc?.showProfile();
}
showWaypoints();
syncWaypointMarkers();
if (trail.id && gpxDataMap[trail.id]) {
addCaretLayer(gpxDataMap[trail.id]);
}
@@ -698,7 +703,6 @@
if (!map) {
return;
}
hideWaypoints();
activeTrail ??= 0;
map.getCanvas().style.cursor = "crosshair";
if (trails[activeTrail]) {
@@ -714,7 +718,7 @@
if (!map) {
return;
}
showWaypoints();
syncWaypointMarkers();
map.getCanvas().style.cursor = "inherit";
if (activeTrail !== null && trails[activeTrail] && !clusterTrails) {
@@ -792,7 +796,7 @@
}
function showWaypoints() {
if (!map || drawing) {
if (!map) {
return;
}
@@ -816,6 +820,14 @@
});
}
function syncWaypointMarkers() {
if (displayWaypoints) {
showWaypoints();
} else {
hideWaypoints();
}
}
function hideWaypoints() {
if (!map) {
return;
@@ -1015,6 +1027,10 @@
onclick?.(e);
});
map.on("contextmenu", (e) => {
oncontextmenu?.(e);
});
map.on("load", () => {
layerManager.init();
initMap(true);
@@ -1022,7 +1038,7 @@
mapLoaded = true;
});
showWaypoints();
syncWaypointMarkers();
});
function geolocate() {

View File

@@ -23,6 +23,7 @@
onRecalculateElevationData: () => void;
onUndo: () => void;
onRedo: () => void;
showWaypoints?: boolean;
resetLabel?: string;
resetAriaLabel?: string;
}
@@ -37,6 +38,7 @@
onRecalculateElevationData,
onUndo,
onRedo,
showWaypoints = $bindable(true),
resetLabel = "reset",
resetAriaLabel = "reset-route",
}: Props = $props();
@@ -149,6 +151,15 @@
aria-label="recalculate elevation data"
onclick={async () => await togglePanels(false, false, !recalculateElevationData)}><i class="fa fa-mountain text-sm"></i></button
>
<button
class="btn-icon tooltip"
class:bg-secondary-hover={showWaypoints}
type="button"
aria-label={$_("waypoints", { values: { n: 2 } })}
data-title={$_("waypoints", { values: { n: 2 } })}
onclick={() => (showWaypoints = !showWaypoints)}
><i class="fa fa-location-dot text-sm"></i></button
>
<button
class="btn-icon tooltip hover:text-red-500"
type="button"

View File

@@ -73,6 +73,11 @@ export function createMarkerFromWaypoint(waypoint: Waypoint, onDragEnd?: (marker
marker.on("dragend", () => onDragEnd(marker, waypoint.id,));
}
marker.getElement().addEventListener("click", (e) => {
e.stopPropagation();
marker.togglePopup();
});
return marker;
}

View File

@@ -136,6 +136,7 @@
let gpxFile: File | Blob | null = null;
let drawingActive = $state(false);
let showWaypointsWhileDrawing = $state(true);
let replacingRoute = $state(false);
let isNewTrail = $derived(page.params.id === "new");
@@ -856,6 +857,16 @@
}
}
function openWaypointActionPopup(lngLat: M.LngLat) {
mapPopup?.remove();
mapPopup = createEditTrailMapPopup(lngLat, () => {
mapPopup?.remove();
beforeWaypointModalOpen(lngLat.lat, lngLat.lng);
});
mapPopup.addTo(map!);
}
async function handleMapClick(e: M.MapMouseEvent) {
if (!drawingActive) {
if (
@@ -865,13 +876,7 @@
) {
return;
}
mapPopup?.remove();
mapPopup = createEditTrailMapPopup(e.lngLat, () => {
mapPopup?.remove();
beforeWaypointModalOpen(e.lngLat.lat, e.lngLat.lng);
});
mapPopup.addTo(map!);
openWaypointActionPopup(e.lngLat);
} else {
const anchorCount = valhallaStore.anchors.length;
if (anchorCount == 0) {
@@ -886,6 +891,20 @@
}
}
function handleMapContextMenu(e: M.MapMouseEvent) {
if (!drawingActive || !showWaypointsWhileDrawing) {
return;
}
if (
(e.originalEvent.target as HTMLElement).tagName.toLowerCase() !==
"canvas"
) {
return;
}
e.preventDefault();
openWaypointActionPopup(e.lngLat);
}
async function addAnchorAndRecalculate(lat: number, lon: number) {
const previousAnchor =
valhallaStore.anchors[valhallaStore.anchors.length - 1];
@@ -1799,8 +1818,10 @@
</div>
{/if}
<hr class="border-input-border" />
{#if isNewTrail || replacingRoute}
<h3 class="text-xl font-semibold">{$_("pick-a-trail")}</h3>
{#if isNewTrail || replacingRoute || drawingActive || $formData.expand?.gpx_data}
{#if isNewTrail || replacingRoute}
<h3 class="text-xl font-semibold">{$_("pick-a-trail")}</h3>
{/if}
<button
class="btn-primary"
type="button"
@@ -2125,6 +2146,7 @@
onRecalculateElevationData={recalculateElevationData}
onUndo={undoRouteEdit}
onRedo={redoRouteEdit}
bind:showWaypoints={showWaypointsWhileDrawing}
></RouteEditor>
</div>
{/if}
@@ -2133,6 +2155,7 @@
trails={mapTrail}
waypoints={$formData.expand?.waypoints_via_trail}
drawing={drawingActive}
displayWaypoints={!drawingActive || showWaypointsWhileDrawing}
showTerrain={true}
autoGeolocateOnDrawing={page.params.id === "new"}
onmarkerdragend={moveMarker}
@@ -2140,6 +2163,7 @@
bind:map
oninit={handleMapInit}
onclick={(target) => handleMapClick(target)}
oncontextmenu={(target) => handleMapContextMenu(target)}
onsegmentclick={(data) => handleSegmentClick(data)}
onsegmentdragend={(data) => handleSegmentDragEnd(data)}
mapOptions={{ preserveDrawingBuffer: true }}