diff --git a/B05_Profile/B05_Profile_UI_RouteEdit.ts b/B05_Profile/B05_Profile_UI_RouteEdit.ts index 3d05ffc66..964be9050 100644 --- a/B05_Profile/B05_Profile_UI_RouteEdit.ts +++ b/B05_Profile/B05_Profile_UI_RouteEdit.ts @@ -56,7 +56,6 @@ import { captureView, createViewMemory, fitCanvas, - fitView, openingView, restoreSavedView, screenToMetric, @@ -92,6 +91,7 @@ import { import type { DesignPageHost } from "../A00_Common/design/design_page"; import * as draftLink from "./B05_Profile_UI_RouteEdit_Draft"; import { bindRouteShift } from "./B05_Profile_UI_RouteEdit_Shift"; +import * as fit from "./logic/B05_Profile_RouteEdit_StationFit"; import "./B05_Profile_UI_Style_RouteEdit.css"; /** 등고선 눈금을 고를 때 쓸 라벨 예산 — B04 지도 기본값(350)보다 **넉넉히** 둔다 @@ -160,7 +160,7 @@ export async function mountRouteEditor( let apexLock: boolean[] = []; /** 지금 고른 꺾임점 — 곡선 편집줄이 이 자리를 만진다. 없으면 -1. */ let picked = -1; - /** [측점 스냅](요구 224-2) — 보기 모드라 되돌리기 밖 · 열 때 서버 값 · [확인] 때 저장. */ + /** [측점 스냅](224-2 · 366-3) — 켬 = 곡선 MC 를 일반측점에 · 켬끔 자체는 되돌리기 밖 · [저장] 때 저장. */ let stationSnap = false; let savedStationSnap = false; /** 편집 창 측점 한 곳 — 끔이면 null(간격마다) · 켬이면 호 안 하나를 곡선 중점으로. @@ -195,7 +195,7 @@ export async function mountRouteEditor( /** 등고선 자물쇠(353-2) — 잠긴 동안 빈 곳 · 다른 가닥을 눌러도 고른 것이 안 바뀜. */ const contourLock = createContourLock( canvas, - () => contours && { layer: contours.layer, view, stepM: contourStepM(), rotation }, + () => contours && { ...contours, view, rotation, stepM: contourStepM(), picked: pickedContour }, (index) => ((pickedContour = index), draw()), ); /** 측점 횡단 미리보기 창 — 측점 눈금을 누르면 뜬다(계획서 0-9 ⑧). */ @@ -266,6 +266,7 @@ export async function mountRouteEditor( const showMinorContours = bindMinorContourToggle(minorContourButton, () => draw()); stationSnapButton.addEventListener("click", () => { setStationSnap(!stationSnap); + if (stationSnap && history) applyEdit("곡선 가운데(MC)를 일반측점에 맞췄습니다."); // 전체 · 한 걸음 void crossPreview.refresh(); // 떠 있는 횡단도 옮긴 측점 규칙으로. draw(); }); @@ -318,13 +319,6 @@ export async function mountRouteEditor( rotation.set(opening.rotationRad); viewReady = true; } - // [맞춤] — 처음 그림과 같은 등고 영역 맞춤(회전 0 · 349-0). 셈은 `_View` 몫. - overlay.querySelector('[data-act="fit"]')!.addEventListener("click", () => { - if (!meta || view.width <= 0 || !planned.length) return; - view = fitView(meta, view, planned, contours?.layer ?? null); - rotation.set(0); - draw(); - }); const toScreen = (vertex: Vertex): [number, number] => meta ? metricToScreen(meta, view, vertex[0], vertex[1]) : [0, 0]; @@ -423,6 +417,7 @@ export async function mountRouteEditor( violationCount: nodeInfo.filter((node) => node.violations.length).length, minRadiusM, fresh: nodeInfo.length === 0, + offStation: stationSnap ? fit.offStationCount(plannedLine, curveInfo, stationIntervalM) : 0, }); // ── 곡선 라벨 — 고른 꺾임점 옆에 뜨는 조작 패널. 배선은 `_CurveBar` 몫 ── @@ -453,8 +448,12 @@ export async function mountRouteEditor( const curveLabelBox = curveBar.label; const syncCurveBar = curveBar.sync; - /** 한 번의 편집을 마무리한다 — 다시 그리고, 라벨·상태줄을 맞추고, 되돌리기에 쌓는다. */ - function applyEdit(message: string, record = true): void { + /** 한 번의 편집을 마무리한다 — 다시 그리고, 라벨·상태줄을 맞추고, 되돌리기에 쌓는다. + * 측점 스냅 켬이면 고친 자리 앞 곡선부터 MC 를 일반측점에(366-3 · 되살림 `fitting=false` 은 안 맞춤). */ + function applyEdit(message: string, record = true, fitting = true): void { + const limits = { minRadiusM, limitRadiusM, limitArcM, intervalM: stationIntervalM }; + const from = fit.fitStart(history?.current?.(), snapshotNow()); + if (stationSnap && fitting) planned = fit.fitCurveStations(snapshotNow(), limits, from); markEdited(); writeRouteLocks(projectId, planned, apexLock); // 고정은 [취소] · 다시 열기에도 남는다(22-5). syncCurveBar(); @@ -484,7 +483,7 @@ export async function mountRouteEditor( const locks = record ? routeLocksOf(planned, apexLock) : null; ({ planned, curveOn, curveRadius, curveLock, curveArc, apexLock, picked } = snapshot); if (locks) apexLock = lockColumn(planned, locks); - applyEdit(message, record); + applyEdit(message, record, false); // 되돌리기 · 추천 [적용] · 초안 되살림은 안 맞춤(366-3) } const historyControls = bindHistoryControls({ @@ -540,6 +539,7 @@ export async function mountRouteEditor( curveHint, contourHint, commit: () => { + if (stationSnap) return applyEdit("곡선 가운데(MC)를 일반측점에 맞췄습니다."); // 놓을 때(366-3) history?.commit(snapshotNow()); historyControls.sync(); }, diff --git a/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts b/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts index 211b0658a..13021c9e8 100644 --- a/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts +++ b/B05_Profile/B05_Profile_UI_RouteEdit_Chrome.ts @@ -11,6 +11,7 @@ import { bindFootprintToggle } from "./B05_Profile_UI_RouteEdit_Footprint"; * **배치**(352-1) — 지도가 칸 전체 · 머리 줄 · 테두리 없음. 도구는 3D 와 같은 떠 있는 유리 단추 * (지도 왼쪽 위 · ☰ 비킴), [?] 조작 설명은 도구줄 아래 2열, 상태·범례는 왼쪽 아래, 잰 값은 오른쪽 * 아래. 횡단 두 판은 지도 오른쪽을 덮는 판(아래 종단 판이 그 위). + * 도구줄 차례(366-2) — [?] | ↶ ↷ | 3D | ⟲ ⟳ · 1m 등고선 · 절/성토선 · 거리 재기 | 측점 스냅 · 분석 지형. * * 자리(345-3) — 모달이 아니라 종단 보기 가운데 위 본문(옛 3D 자리)에 붙는다. 덮개 · 전체 화면 · * 닫기 단추는 걷었다 · [취소] · [확인] · [노선 반영] · [저장 전으로]는 없앰(346-3 · 352-2 — 노선은 페이지 @@ -60,8 +61,31 @@ export function createRouteEditChrome(
+ + + + + + + + + + + + - - - - - - - -
-
노드 끌기 = 옮기기노드 클릭 = R 라벨 선 두 번 클릭 = 노드 추가노드 오른쪽 클릭 = 삭제 @@ -97,12 +102,6 @@ export function createRouteEditChrome( 가운데(휠) 버튼 끌기 = 지도 이동휠 = 확대
-
- - -