From 069a59842998c981a0e1cb0e736fea19f7e6a77c Mon Sep 17 00:00:00 2001 From: vcoppe Date: Tue, 13 Aug 2024 14:58:15 +0200 Subject: [PATCH] extract redundant code in helper function --- gpx/src/simplify.ts | 4 +-- .../toolbar/tools/routing/RoutingControls.ts | 34 +++++++------------ website/src/lib/db.ts | 14 +++----- website/src/lib/utils.ts | 15 ++++++++ 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/gpx/src/simplify.ts b/gpx/src/simplify.ts index 5f9884e7..69da3682 100644 --- a/gpx/src/simplify.ts +++ b/gpx/src/simplify.ts @@ -45,8 +45,8 @@ function ramerDouglasPeuckerRecursive(points: TrackPoint[], epsilon: number, mea } } -export function crossarcDistance(point1: TrackPoint, point2: TrackPoint, point3: TrackPoint): number { - return crossarc(point1.getCoordinates(), point2.getCoordinates(), point3.getCoordinates()); +export function crossarcDistance(point1: TrackPoint, point2: TrackPoint, point3: TrackPoint | Coordinates): number { + return crossarc(point1.getCoordinates(), point2.getCoordinates(), point3 instanceof TrackPoint ? point3.getCoordinates() : point3); } function crossarc(coord1: Coordinates, coord2: Coordinates, coord3: Coordinates): number { diff --git a/website/src/lib/components/toolbar/tools/routing/RoutingControls.ts b/website/src/lib/components/toolbar/tools/routing/RoutingControls.ts index 3651341f..0c297a88 100644 --- a/website/src/lib/components/toolbar/tools/routing/RoutingControls.ts +++ b/website/src/lib/components/toolbar/tools/routing/RoutingControls.ts @@ -10,7 +10,7 @@ import { dbUtils, type GPXFileWithStatistics } from "$lib/db"; import { getOrderedSelection, selection } from "$lib/components/file-list/Selection"; import { ListFileItem, ListTrackItem, ListTrackSegmentItem } from "$lib/components/file-list/FileList"; import { currentTool, streetViewEnabled, Tool } from "$lib/stores"; -import { resetCursor, setGrabbingCursor } from "$lib/utils"; +import { getClosestLinePoint, resetCursor, setGrabbingCursor } from "$lib/utils"; export const canChangeStart = writable(false); @@ -339,17 +339,16 @@ export class RoutingControls { let minAnchor = this.temporaryAnchor as Anchor; file?.forEachSegment((segment, trackIndex, segmentIndex) => { if (get(selection).hasAnyParent(new ListTrackSegmentItem(this.fileId, trackIndex, segmentIndex))) { - for (let i = 0; i < segment.trkpt.length - 1; i++) { - let dist = crossarcDistance(segment.trkpt[i], segment.trkpt[i + 1], this.temporaryAnchor.point); - if (dist < minDistance) { - minDistance = dist; - minAnchor = { - point: segment.trkpt[i], - segment, - trackIndex, - segmentIndex, - }; - } + let details: any = {}; + let closest = getClosestLinePoint(segment.trkpt, this.temporaryAnchor.point, details); + if (details.distance < minDistance) { + minDistance = details.distance; + minAnchor = { + point: closest, + segment, + trackIndex, + segmentIndex + }; } } }); @@ -539,16 +538,7 @@ export class RoutingControls { for (let i = 1; i < anchors.length - 1; i++) { // Find the closest point to the intermediate anchor // and transfer the marker to that point - let minDistance = Number.MAX_VALUE; - let minIndex = 0; - for (let j = 1; j < response.length - 1; j++) { - let dist = distance(response[j].getCoordinates(), targetCoordinates[i]); - if (dist < minDistance) { - minDistance = dist; - minIndex = j; - } - } - anchors[i].point = response[minIndex]; + anchors[i].point = getClosestLinePoint(response.slice(1, - 1), targetCoordinates[i]); } anchors.forEach((anchor) => { diff --git a/website/src/lib/db.ts b/website/src/lib/db.ts index 9df3dba5..5763b3a7 100644 --- a/website/src/lib/db.ts +++ b/website/src/lib/db.ts @@ -2,13 +2,13 @@ import Dexie, { liveQuery } from 'dexie'; import { GPXFile, GPXStatistics, Track, TrackSegment, Waypoint, TrackPoint, type Coordinates, distance, type LineStyleExtension, type WaypointType } from 'gpx'; import { enableMapSet, enablePatches, applyPatches, type Patch, type WritableDraft, freeze, produceWithPatches } from 'immer'; import { writable, get, derived, type Readable, type Writable } from 'svelte/store'; -import { Tool, currentTool, gpxStatistics, initTargetMapBounds, map, splitAs, updateAllHidden, updateTargetMapBounds } from './stores'; +import { gpxStatistics, initTargetMapBounds, map, splitAs, updateAllHidden, updateTargetMapBounds } from './stores'; import { defaultBasemap, defaultBasemapTree, defaultOverlayTree, defaultOverlays, type CustomLayer, defaultOpacities, defaultOverpassQueries, defaultOverpassTree } from './assets/layers'; import { applyToOrderedItemsFromFile, applyToOrderedSelectedItemsFromFile, selection } from '$lib/components/file-list/Selection'; import { ListFileItem, ListItem, ListTrackItem, ListLevel, ListTrackSegmentItem, ListWaypointItem, ListRootItem } from '$lib/components/file-list/FileList'; import { updateAnchorPoints } from '$lib/components/toolbar/tools/routing/Simplify'; import { SplitType } from '$lib/components/toolbar/tools/scissors/Scissors.svelte'; -import { getElevation } from '$lib/utils'; +import { getClosestLinePoint, getElevation } from '$lib/utils'; import { browser } from '$app/environment'; @@ -813,14 +813,8 @@ export const dbUtils = { let minIndex = 0; if (trkptIndex === undefined) { // Find the point closest to split - let minDistance = Number.MAX_VALUE; - for (let i = 0; i < segment.trkpt.length; i++) { - let dist = distance(segment.trkpt[i].getCoordinates(), coordinates); - if (dist < minDistance) { - minDistance = dist; - minIndex = i; - } - } + let closest = getClosestLinePoint(segment.trkpt, coordinates); + minIndex = closest._data.index; } else { minIndex = trkptIndex; } diff --git a/website/src/lib/utils.ts b/website/src/lib/utils.ts index 1d789efd..2306708e 100644 --- a/website/src/lib/utils.ts +++ b/website/src/lib/utils.ts @@ -9,6 +9,7 @@ import { browser } from "$app/environment"; import { languages } from "$lib/languages"; import { locale } from "svelte-i18n"; import type mapboxgl from "mapbox-gl"; +import { type TrackPoint, type Coordinates, crossarcDistance } from "gpx"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); @@ -68,6 +69,20 @@ export const flyAndScale = ( }; }; +export function getClosestLinePoint(points: TrackPoint[], point: TrackPoint | Coordinates, details: any = {}): TrackPoint { + let closest = points[0]; + let closestDist = Number.MAX_VALUE; + for (let i = 0; i < points.length - 1; i++) { + let dist = crossarcDistance(points[i], points[i + 1], point); + if (dist < closestDist) { + closest = points[i]; + closestDist = dist; + } + } + details['distance'] = closestDist; + return closest; +} + export function getElevation(map: mapboxgl.Map, coordinates: Coordinates): number { let elevation = map.queryTerrainElevation(coordinates, { exaggerated: false }); return elevation === null ? 0 : elevation;