From 213737289ee0442cd1bdc2381dbeff88ad083f8e Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 29 Aug 2026 11:01:07 +0900 Subject: [PATCH] =?UTF-8?q?fix(B06):=20=EB=8B=A4=EB=8B=A8=20=EA=B5=AC?= =?UTF-8?q?=EA=B0=84=EA=B0=92=20=EA=B8=B0=EB=B3=B8=EC=9D=84=20=EC=86=8C?= =?UTF-8?q?=EC=9C=A0=20=EB=B2=BD=20=EC=97=B0=EC=9E=A5=20=EC=83=81=EC=86=8D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B0=94=EA=BE=BC=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 고정 10m(전/후 5)를 기본으로 두니 소유 벽 연장(유출 12m·유입 21.5m)보다 짧아, +5.9m 떨어진 링크 카드에서 기준벽은 서는데 다단만 사라졌다. 손대기 전에는 기준벽 연장을 그대로 따르고, 손으로 잡은 단만 그 값으로 고정한다. - tierSpanOf: 저장값 → 소유 벽 연장(유출측은 유출 벽, 유입측은 유입 벽/집수정) → 마지막으로 10m(5/5). 그리기·링크 판정·조정창 표시가 이 함수 하나를 쓴다 Co-Authored-By: Claude Opus 5 (1M context) --- .../B06_Section_UI_Cross_Culvert_Wire.ts | 12 ++++++-- .../B06_Section_UI_Page_Station_Controls.ts | 28 +++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/B06_Section/B06_Section_UI_Cross_Culvert_Wire.ts b/B06_Section/B06_Section_UI_Cross_Culvert_Wire.ts index 19190abc..35b1261b 100644 --- a/B06_Section/B06_Section_UI_Cross_Culvert_Wire.ts +++ b/B06_Section/B06_Section_UI_Cross_Culvert_Wire.ts @@ -139,12 +139,18 @@ export interface CulvertLink { /** * 다단 한 단의 구간값 — 단별로 따로 잡은 값(`design.extra_spans`)이 있으면 그것, - * 없으면 고정 기본 10m(5/5). 기준벽 연장을 상속하지 않는다(2026-08-29 사용자). + * **없으면 소유 벽 연장을 상속**한다(2026-08-30 사용자: 손대기 전에는 기준벽과 같이 + * 옆 측점에 서야 한다). 고정 기본 10m(5/5)는 소유 벽 제원조차 없을 때의 마지막 값이다. + * 손으로 한 번 잡은 단은 그 값으로 고정된다 — 계곡부·능선부에서 단마다 연장이 다르다. */ export function tierSpanOf(section: CrossSection, key: string): StructureSpan { const stored = section.design?.extra_spans?.[key]; - if (!stored) return { ...EXTRA_SPAN_DEFAULT }; - return { beforeM: Math.max(stored.before_m, 0), afterM: Math.max(stored.after_m, 0) }; + if (stored) return { beforeM: Math.max(stored.before_m, 0), afterM: Math.max(stored.after_m, 0) }; + // 유출측 다단(extra…)은 유출 벽, 유입측 다단(bextra…)은 유입 벽(집수정이면 집수정) + // 연장을 따른다 — 그 벽에 딸린 성토부 계단이기 때문이다. + const spec = key.startsWith("bextra") ? section.culvert?.inlet : section.culvert?.outlet; + if (!spec) return { ...EXTRA_SPAN_DEFAULT }; + return spec.structure === "집수정" ? basinSpanOfSpec(spec) : revetSpanOfSpec(spec); } /** 구조물이 종방향으로 덮는 범위(기준측점 전/후 m) — 기슭막이·집수정·다단 중 큰 값. */ diff --git a/B06_Section/B06_Section_UI_Page_Station_Controls.ts b/B06_Section/B06_Section_UI_Page_Station_Controls.ts index 45f6927b..dbb6f0dd 100644 --- a/B06_Section/B06_Section_UI_Page_Station_Controls.ts +++ b/B06_Section/B06_Section_UI_Page_Station_Controls.ts @@ -24,7 +24,7 @@ import type { StructureSpanControl, } from "./B06_Section_UI_Cross_View"; import * as CulvertConst from "./B06_Section_UI_Cross_Culvert_Const"; -import { culvertOwnerFor } from "./B06_Section_UI_Cross_Culvert_Wire"; +import { culvertOwnerFor, tierSpanOf } from "./B06_Section_UI_Cross_Culvert_Wire"; import { createCulvertOptionWriter } from "./B06_Section_Api_Culvert_Options"; import { createBodyControls } from "./B06_Section_UI_Page_Ford_Controls"; import { createLinkFlagSession } from "./B06_Section_UI_Page_Link_Session"; @@ -552,14 +552,17 @@ export function createStationControls(deps: StationControlDeps): StationControls } } - /** 정본(design)에 남은 단별 구간값 — 세션에 없을 때의 다음 후보. */ - const storedTierSpan = (owner: CrossSection, wall: string): SpanValues | null => { - const stored = owner.design?.extra_spans?.[wall]; - if (!stored) return null; + /** + * 세션에 없을 때의 단별 구간값 — 정본(`design.extra_spans`) → **소유 벽 연장 상속** + * 순서다(2026-08-30 사용자: 손대기 전에는 기준벽과 같이 옆 측점에 서야 한다). + * 상속 규칙은 그리기·링크 판정이 쓰는 `tierSpanOf`와 같은 함수 하나로 맞춘다. + */ + const storedTierSpan = (owner: CrossSection, wall: string): SpanValues => { + const span = tierSpanOf(owner, wall); return { - lengthM: stored.length_m, - beforeM: stored.before_m, - afterM: stored.after_m, + lengthM: Math.round((span.beforeM + span.afterM) * 10) / 10, + beforeM: Math.round(span.beforeM * 10) / 10, + afterM: Math.round(span.afterM * 10) / 10, }; }; @@ -582,18 +585,13 @@ export function createStationControls(deps: StationControlDeps): StationControls ownerOf, tierValuesFor: (section, key) => { const owner = ownerOf(section) ?? section; - return ( - extraSpans.get(spanKeyOf(owner.chainage_m, key)) ?? - storedTierSpan(owner, key) ?? - CulvertConst.EXTRA_SPAN_DEFAULT - ); + return extraSpans.get(spanKeyOf(owner.chainage_m, key)) ?? storedTierSpan(owner, key); }, updateTier: (section, key, patch) => { const owner = ownerOf(section); if (!owner) return; const mapKey = spanKeyOf(owner.chainage_m, key); - const current = - extraSpans.get(mapKey) ?? storedTierSpan(owner, key) ?? CulvertConst.EXTRA_SPAN_DEFAULT; + const current = extraSpans.get(mapKey) ?? storedTierSpan(owner, key); const next = CulvertConst.applySpanPatch(current, patch); extraSpans.set(mapKey, next); persistExtraSpans();