diff --git a/package-lock.json b/package-lock.json index 687ba4b09f..bfb78b7c99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@turf/area": "^7.0.0", "@turf/bbox": "^7.0.0", "@turf/bearing": "^7.0.0", + "@turf/center": "^7.0.0", "@turf/destination": "^7.0.0", "@turf/distance": "^7.0.0", "@turf/length": "^7.0.0", @@ -1097,6 +1098,19 @@ "url": "https://opencollective.com/turf" } }, + "node_modules/@turf/center": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@turf/center/-/center-7.0.0.tgz", + "integrity": "sha512-5RZia9uuWxz2oCyd1vsNkBeraBNdwCsIo4UGRQdyswBeLFVbRwIUa7M7+2z2D7B1YIgovuLIRVfk6FeWUQXDtQ==", + "dependencies": { + "@turf/bbox": "^7.0.0", + "@turf/helpers": "^7.0.0", + "tslib": "^2.6.2" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, "node_modules/@turf/destination": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@turf/destination/-/destination-7.0.0.tgz", diff --git a/package.json b/package.json index df388a7194..3df4e2e596 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@turf/area": "^7.0.0", "@turf/bbox": "^7.0.0", "@turf/bearing": "^7.0.0", + "@turf/center": "^7.0.0", "@turf/destination": "^7.0.0", "@turf/distance": "^7.0.0", "@turf/length": "^7.0.0", diff --git a/src/routes/route_check/jat_check/EditJunction.svelte b/src/routes/route_check/jat_check/EditJunction.svelte index 67c638c7fd..53ba12b456 100644 --- a/src/routes/route_check/jat_check/EditJunction.svelte +++ b/src/routes/route_check/jat_check/EditJunction.svelte @@ -134,8 +134,9 @@ }; function autogenerateMovements() { - let [center, ...arms] = $state.jat[junctionIdx][stage].arms; - $state.jat[junctionIdx][stage].movements = generateMovements(center, arms); + $state.jat[junctionIdx][stage].movements = generateMovements( + $state.jat[junctionIdx][stage].arms, + ); } @@ -196,7 +197,7 @@

{#if $state.jat[junctionIdx][stage].arms.length > 0} - Generate cycling movements between all arms (1st arm is the center) + Generate cycling movements between all arms {/if} {#each $state.jat[junctionIdx][stage].movements as movement, idx} diff --git a/src/routes/route_check/jat_check/generate.ts b/src/routes/route_check/jat_check/generate.ts index 4523003b21..6fbcc125ff 100644 --- a/src/routes/route_check/jat_check/generate.ts +++ b/src/routes/route_check/jat_check/generate.ts @@ -3,12 +3,13 @@ import type { Position } from "$lib/map"; import destination from "@turf/destination"; import bearing from "@turf/bearing"; import distance from "@turf/distance"; +import turfCenter from "@turf/center"; -export function generateMovements(center: Arm, arms: Arm[]): Movement[] { +export function generateMovements(arms: Arm[]): Movement[] { let spacingMeters = 0.003; let jitter = (idx: number, offset: number) => { let pt = arms[idx].point; - let angleToCenter = bearing(pt, center.point); + let angleToCenter = bearing(pt, center); // This should wind up on the left side of the road let perpAngle = angleToCenter - 90; let projectDistance = spacingMeters * offset; @@ -18,26 +19,38 @@ export function generateMovements(center: Arm, arms: Arm[]): Movement[] { }; // Sort arms around center in CCW order + let center = turfCenter({ + type: "FeatureCollection", + features: arms.map((arm) => { + return { + type: "Feature", + geometry: { + type: "Point", + coordinates: arm.point, + }, + }; + }), + }).geometry.coordinates; arms.sort( (a1, a2) => - normalize(bearing(center.point, a2.point)) - - normalize(bearing(center.point, a1.point)), + normalize(bearing(center, a2.point)) - + normalize(bearing(center, a1.point)), ); let movements = []; for (let i = 0; i < arms.length; i++) { let arm1 = arms[i]; - let angleStartToCenter = bearing(arm1.point, center.point); + let angleStartToCenter = bearing(arm1.point, center); // Continue in order let toCount = 1; for (let j of order(i, arms.length)) { let arm2 = arms[j]; - let angleCenterToEnd = bearing(center.point, arm2.point); + let angleCenterToEnd = bearing(center, arm2.point); // Start at the arm, far from the junction let point1 = jitter(i, toCount++); // Then go some percent towards the junction - let dist = distance(arm1.point, center.point); + let dist = distance(arm1.point, center); let point2 = destination(point1, 0.5 * dist, angleStartToCenter).geometry .coordinates as Position; let point3 = destination(point2, 0.2 * dist, angleCenterToEnd).geometry