fix(B06): 폼 형태·높이를 지금 그려진 값으로 맞춘다

배관 유출구 기슭막이가 폼과 다른 형태로 그려졌다. 폼은 저장된 옵션을,
그림은 조정값(m·h)을 쓰는데 둘이 어긋나도 맞추는 자리가 없었다.
조작이 정본이므로 폼이 그려진 값을 따라간다 — wallForm 의존성을 추가하고
형태·높이는 빈칸 채우기가 아니라 덮어쓰기로 바꾼다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-29 18:42:33 +09:00
co-authored by Claude Opus 5
parent 07089e285a
commit f7ec239625
2 changed files with 33 additions and 4 deletions
+13
View File
@@ -151,6 +151,19 @@ export async function renderB06ProfileCross(root: HTMLElement): Promise<void> {
return revetWallSpec(spec, adjust, culvert.hidden_pipe === true, culvert.diameter_m)
.pureHeight;
},
// 폼 형태 = 지금 도면이 쓰는 형태. 조작(조정값 m)이 있으면 그것이 정본이라
// 저장된 옵션보다 앞선다 — 안 맞추면 폼은 저장값, 그림은 조작값이 되어
// "유출구 형태를 바꿔도 안 바뀐다"로 보인다(2026-08-30 사용자 보고).
wallForm: (chainageM, role) => {
const owner = sectionDetail?.cross_sections.find(
(section) => Math.abs(section.chainage_m - chainageM) < 0.51,
);
const culvert = owner?.culvert;
if (!owner || !culvert) return null;
const spec = role === "outlet" ? culvert.outlet : culvert.inlet;
const adjust = stationControls.revetOffset.adjustFor(owner, role);
return revetWallSpec(spec, adjust, culvert.hidden_pipe === true, culvert.diameter_m).form;
},
stationInterval: () => stationInterval ?? 20,
focusChainage: focusStationAt,
queuePipeOptions: (chainageM, patch) => stationControls.queueCulvertOptions(chainageM, patch),
@@ -43,6 +43,8 @@ export interface B06StructuresPanelDeps {
/** 지금 그려진 벽 높이(m) — 배관 벽은 스펙이 아니라 기하가 정하므로 폼 기본
* 높이도 이 값을 쓴다(조정창 표시값과 같다). */
wallHeight?: (chainageM: number, role: "inlet" | "outlet") => number | null;
/** 지금 그려진 벽 형태 — 조정값(m)이 있으면 그쪽이 정본이라 폼도 이 값을 보인다. */
wallForm?: (chainageM: number, role: "inlet" | "outlet") => string | null;
/** 측점 간격(m) — 측점번호+잔여거리 환산용. */
stationInterval: () => number;
/** 목록·폼에서 고른 시설의 측점 카드를 선택·스크롤한다. */
@@ -103,6 +105,7 @@ function withSpecDefaults(
detail: SectionDetailResponse | null,
chainageM: number,
wallHeight?: (chainageM: number, role: "inlet" | "outlet") => number | null,
wallForm?: (chainageM: number, role: "inlet" | "outlet") => string | null,
): Record<string, string | number> | undefined {
const owner = detail?.cross_sections.find(
(section) => Math.abs(section.chainage_m - chainageM) < PIPE_MATCH_M,
@@ -120,9 +123,15 @@ function withSpecDefaults(
[culvert.outlet, "outlet"],
] as const) {
put(`${prefix}_type`, side.structure);
put(`${prefix}_revet_form`, side.revet_form);
// 높이는 기하가 정한 실제 값이 기준이다 — 못 구하면 스펙 값으로 물러난다.
put(`${prefix}_revet_height_m`, wallHeight?.(chainageM, prefix) ?? side.revet_height_m);
// 형태·높이는 **지금 그려진 값**이 이긴다 — 조정값(조작)이 저장된 옵션보다
// 앞서기 때문이다. 저장값을 그대로 두면 폼과 그림이 갈린다(2026-08-30 사용자:
// 배관 유출구 기슭막이 형태가 폼과 다르게 그려졌다).
const drawnForm = wallForm?.(chainageM, prefix);
if (drawnForm) merged[`${prefix}_revet_form`] = drawnForm;
else put(`${prefix}_revet_form`, side.revet_form);
const drawnHeight = wallHeight?.(chainageM, prefix);
if (drawnHeight != null) merged[`${prefix}_revet_height_m`] = Number(drawnHeight.toFixed(1));
else put(`${prefix}_revet_height_m`, side.revet_height_m);
put(`${prefix}_revet_length_m`, side.revet_length_m);
put(`${prefix}_revet_before_m`, side.revet_before_m);
put(`${prefix}_revet_after_m`, side.revet_after_m);
@@ -239,7 +248,13 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc
end_m: pipe.end_m,
source: pipe.source,
// 폼 기본값 = 조정창이 쓰던 값(횡단 스펙). 저장된 옵션이 있으면 그쪽이 이긴다.
options: withSpecDefaults(pipe.options, detail, pipe.chainage_m, deps.wallHeight),
options: withSpecDefaults(
pipe.options,
detail,
pipe.chainage_m,
deps.wallHeight,
deps.wallForm,
),
design_flow_m3s: null,
}));
section.setPipeFacilities(pipeFacilities);
@@ -262,6 +277,7 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc
deps.detail?.() ?? null,
hit.chainage_m,
deps.wallHeight,
deps.wallForm,
);
section.setPipeFacilities(pipeFacilities);
}