diff --git a/web/src/lib/components/trail/map_with_elevation_maplibre.svelte b/web/src/lib/components/trail/map_with_elevation_maplibre.svelte index a5943b9d..550f2eeb 100644 --- a/web/src/lib/components/trail/map_with_elevation_maplibre.svelte +++ b/web/src/lib/components/trail/map_with_elevation_maplibre.svelte @@ -55,6 +55,10 @@ segment: number; event: M.MapMouseEvent; }) => void; + onsegmentclick?: (data: { + segment: number; + event: M.MapMouseEvent; + }) => void; onselect?: (trail: Trail) => void; onunselect?: (trail: Trail) => void; onfullscreen?: () => void; @@ -87,6 +91,7 @@ clusterTrails = false, onmarkerdragend, onsegmentdragend, + onsegmentclick, onselect, onunselect, onfullscreen, @@ -408,7 +413,7 @@ activeTrail = trails.findIndex((t) => t.id == trail.id); }; layers[id].listener.onMouseMove = moveCrosshairToCursorPosition; - layers[id].listener.onMouseDown = (e) => handDragStart(e, id); + layers[id].listener.onMouseDown = (e) => handleDragStart(e, id); map.on("mouseenter", id, layers[id].listener.onEnter); map.on("mouseleave", id, layers[id].listener.onLeave); @@ -529,7 +534,7 @@ elevationMarker.setLngLat(e.lngLat); } - function handDragStart(e: M.MapMouseEvent, id: string) { + function handleDragStart(e: M.MapMouseEvent, id: string) { if ( !drawing || (e.originalEvent.target as HTMLElement | null)?.classList.contains( @@ -549,13 +554,21 @@ } map?.on("mousemove", moveElevationMarkerToCursorPosition); - map?.once("mouseup", handleDragEnd); + map?.once("mouseup", (e2) => handleDragEnd(e2, e)); } - function handleDragEnd(e: M.MapMouseEvent) { + function handleDragEnd(end: M.MapMouseEvent, start: M.MapMouseEvent) { map?.off("mousemove", moveElevationMarkerToCursorPosition); epc?.hideCrosshair(); - onsegmentdragend?.({ segment: draggingSegment!, event: e }); + const distanceDragged = Math.sqrt( + Math.pow(end.originalEvent.x - start.originalEvent.x, 2) + + Math.pow(end.originalEvent.y - start.originalEvent.y, 2), + ); + if (distanceDragged < 0.5) { + onsegmentclick?.({ segment: draggingSegment!, event: end }); + } else { + onsegmentdragend?.({ segment: draggingSegment!, event: end }); + } draggingSegment = null; } @@ -1096,7 +1109,7 @@ map!.getCanvas().style.cursor = ""; }); - map.on("load", () => { + map.on("load", () => { initMap(true); layerManager.init(); oninit?.(map!); diff --git a/web/src/lib/components/trail/route_editor.svelte b/web/src/lib/components/trail/route_editor.svelte index 08123d57..cf2598da 100644 --- a/web/src/lib/components/trail/route_editor.svelte +++ b/web/src/lib/components/trail/route_editor.svelte @@ -121,7 +121,7 @@ recalculateElevationData = false; crop = false; editRoute = !editRoute; - }}> { - removeAnchor(valhallaStore.anchors.findIndex((a) => a.id == anchor.id)); + removeAnchor( + valhallaStore.anchors.findIndex((a) => a.id == anchor.id), + ); }, () => { - const thisAnchor = valhallaStore.anchors.find((a) => a.id == anchor.id); + const thisAnchor = valhallaStore.anchors.find( + (a) => a.id == anchor.id, + ); addAnchorAndRecalculate( thisAnchor?.lat ?? lat, thisAnchor?.lon ?? lon, @@ -794,7 +809,9 @@ } async function recalculateRoute(anchorIndex: number) { - const markerText = startAnchorLoading(valhallaStore.anchors[anchorIndex]); + const markerText = startAnchorLoading( + valhallaStore.anchors[anchorIndex], + ); const anchor = valhallaStore.anchors[anchorIndex]; if (!anchor) { @@ -860,21 +877,8 @@ data.segment + 1, ); const markerText = startAnchorLoading(anchor); + updateFollowingAnchors(data.segment); - for (let i = data.segment + 2; i < valhallaStore.anchors.length; i++) { - const anchor = valhallaStore.anchors[i]; - const markerIcon = anchor.marker?.getElement(); - if (markerIcon) { - const markerText = markerIcon.textContent ?? "0"; - const markerIndex = parseInt(markerText); - const newIndex = markerIndex + 1; - markerIcon.textContent = newIndex + ""; - anchor - .marker!.getPopup() - ._content.getElementsByTagName("h5")[0].textContent = - $_("route-point") + " #" + newIndex; - } - } const previousAnchor = valhallaStore.anchors[data.segment]; const nextAnchor = valhallaStore.anchors[data.segment + 2]; @@ -910,6 +914,37 @@ } } + function updateFollowingAnchors(segment: number) { + for (let i = segment + 2; i < valhallaStore.anchors.length; i++) { + const anchor = valhallaStore.anchors[i]; + const markerIcon = anchor.marker?.getElement(); + if (markerIcon) { + const markerText = markerIcon.textContent ?? "0"; + const markerIndex = parseInt(markerText); + const newIndex = markerIndex + 1; + markerIcon.textContent = newIndex + ""; + anchor + .marker!.getPopup() + ._content.getElementsByTagName("h5")[0].textContent = + $_("route-point") + " #" + newIndex; + } + } + } + + async function handleSegmentClick(data: { + segment: number; + event: M.MapMouseEvent; + }) { + addAnchor( + data.event.lngLat.lat, + data.event.lngLat.lng, + data.segment + 1, + ); + + splitSegment(data.segment, data.event.lngLat); + updateFollowingAnchors(data.segment); + } + function reverseTrail() { reverseRoute(); @@ -935,20 +970,27 @@ } else { cropStartMarker?.setOpacity("0"); cropEndMarker?.setOpacity("0"); + const totals = valhallaStore.route.features; + $formData.distance = totals.distance; + $formData.duration = totals.duration / 1000; + $formData.elevation_gain = totals.elevationGain; + $formData.elevation_loss = totals.elevationLoss; } } function updateCropMarkers(range: [start: number, end: number]) { const [start, end] = range; - const targetStartDistance = valhallaStore.route.features.distance * (start / 100); + const targetStartDistance = + valhallaStore.route.features.distance * (start / 100); const [startLon, startLat, startIndex] = getCoordinateAtDistance( flatRoute, valhallaStore.route.features.cumulativeDistance, targetStartDistance, ); - const targetEndDistance = valhallaStore.route.features.distance * (end / 100); + const targetEndDistance = + valhallaStore.route.features.distance * (end / 100); const [endLon, endLat, endIndex] = getCoordinateAtDistance( flatRoute, valhallaStore.route.features.cumulativeDistance, @@ -958,7 +1000,11 @@ cropStartMarker.setLngLat([startLon, startLat]); cropEndMarker.setLngLat([endLon, endLat]); - croppedGPX = cropGPX(flatRoute[startIndex], flatRoute[endIndex], valhallaStore.route); + croppedGPX = cropGPX( + flatRoute[startIndex], + flatRoute[endIndex], + valhallaStore.route, + ); const totals = croppedGPX.features; $formData.distance = totals.distance; $formData.duration = totals.duration / 1000; @@ -1425,8 +1471,8 @@ {#if drawingActive} handleMapClick(target)} + onsegmentclick={(data) => handleSegmentClick(data)} onsegmentdragend={(data) => handleSegmentDragEnd(data)} mapOptions={{ preserveDrawingBuffer: true }} >