/* ============================================================================= * B06_Section_UI_Page_Patches.ts * 확정·임시저장이 보내는 **측점별 편집분(cross_patches) 조립** — 페이지 * (`_UI_Page.ts`)에서 700줄 제한으로 분리했다(2026-08-25). * * 세션·제어기에 흩어져 있던 조작값을 누가거리 하나로 합친다. 값은 만들지 않고 * 모으기만 한다 — 판정·한계는 각 제어기가 이미 끝냈다. * ========================================================================== */ import type { CrossSectionPatch, StoredWallAdjust, StoredWallSpan } from "./B06_Section_Api_Fetch"; import type { BasinAdjust } from "./B06_Section_UI_Cross_Culvert_Types"; import type { FordAdjust } from "./B06_Section_UI_Cross_Ford"; import type { BoxAdjust } from "./B06_Section_UI_Cross_Box"; import type { InletStructureChoice } from "./B06_Section_UI_Cross_Culvert"; export interface CrossPatchSources { /** 암 경계선 오프셋(누가거리 문자열 키). */ rockOffsets: Map; /** 측점별 암 절토 경사비(1:n 의 n). **0 은 「표준값을 씀」**(되돌리기)이다. */ cutSlopeRatios: Map; /** 측점 개별 표시 반폭(m). */ stationWidths: Map; inletStructures: Map; basinAdjustments: Map; revetAdjusts: Map>; extraCounts: Map; /** 다단 단별 구간값(2026-08-29) — 키는 벽 키("extra0"…/"bextra0"…). */ extraSpans: Map>; fordAdjusts: Map; boxAdjusts: Map; linkFlags: Map; } /** 누가거리별 패치를 합쳐 한 배열로 돌려준다. */ export function buildCrossPatches(sources: CrossPatchSources): CrossSectionPatch[] { const patchByChainage = new Map(); const patchFor = (chainageM: number): CrossSectionPatch => { const existing = patchByChainage.get(chainageM); if (existing) return existing; const created: CrossSectionPatch = { chainage_m: chainageM }; patchByChainage.set(chainageM, created); return created; }; sources.rockOffsets.forEach((offset, chainage) => { patchFor(Number(chainage)).rock_boundary_offset_m = offset; }); // 측점별 암 절토 경사(2026-09-07) — 0 이면 「표준값을 씀」이라 정본의 옛 값을 덮어 지운다. sources.cutSlopeRatios.forEach((ratio, chainage) => { patchFor(Number(chainage)).cut_slope_ratio_user = ratio; }); // 개별 표시 반폭(2026-08-06) — design에 병합돼 재접근 시 유지된다. sources.stationWidths.forEach((width, chainage) => { patchFor(Number(chainage)).display_half_width_m = width; }); sources.inletStructures.forEach((structure, chainage) => { patchFor(Number(chainage)).inlet_structure = structure; }); sources.basinAdjustments.forEach((adjust, chainage) => { patchFor(Number(chainage)).basin_adjust = adjust; }); // 기슭막이 4축·다단 단 수 — 세션 전용이던 값을 정본에 실어 확정한다(2026-08-24). sources.revetAdjusts.forEach((adjusts, chainage) => { patchFor(chainage).revet_adjust = adjusts; }); sources.extraCounts.forEach((counts, chainage) => { patchFor(chainage).extra_wall_counts = counts; }); // 다단 단별 구간값 — 세션에서 만진 값을 정본에 싣는다(2026-08-29 사용자). sources.extraSpans.forEach((spans, chainage) => { patchFor(chainage).extra_spans = spans; }); // 세월교 측벽 조작값(2026-08-25) — 배수관 값과 같은 자리에 실어 3D·재계산이 잇는다. sources.fordAdjusts.forEach((adjust, chainage) => { patchFor(chainage).ford_adjust = adjust; }); sources.boxAdjusts.forEach((adjust, chainage) => { patchFor(chainage).box_adjust = adjust; }); // 연동 해제(측점별)·종단경사 반영(전체 공통) — 같은 체계로 정본에 싣는다. sources.linkFlags.forEach((flags, chainage) => { if (flags.detached !== undefined) patchFor(chainage).revet_link_detached = flags.detached; if (flags.followGrade !== undefined) patchFor(chainage).revet_follow_grade = flags.followGrade; }); return [...patchByChainage.values()]; }