/* ============================================================================= * B06_Section_UI_Page_Structure_Pick.ts * B05 3D에서 고른 구조물을 **B06 화면에 얹는다**(2026-09-04 사용자 확정) — 그 측점 * 카드를 고르고 화면에 드러낸 뒤, 부재키가 있으면 그 시설의 조정창까지 연다. * * 부재키는 **횡단도가 그 부재를 부르는 이름 그대로**다. 이름이 겹쳐도(배수관 유입 ↔ * 세월교 유입) 한 측점에는 시설이 하나뿐이라 헷갈리지 않는다 — 그 측점이 세월교면 * 세월교 조정창, BOX암거면 BOX 조정창, 아니면 기슭막이 조정창으로 보낸다. * 본체(`body` — 세월교 월류부 상판·BOX 구체)는 고르는 부재가 아니라 카드까지만 연다. * * 세월교·BOX는 조정창 하나가 그 측 부재 여럿(벽·바닥·날개벽·에이프런)을 함께 다루므로 * 부재키가 `측이름:부재`(예 `inlet:wall`) 꼴이다 — **앞칸이 조정창 이름**이다. 3D 강조는 * 부재 하나만 켜야 해서 뒤칸까지 나눠 두었다(2026-09-04 사용자 확정). * ========================================================================== */ import type { SectionDetailResponse } from "./B06_Section_Api_Fetch"; import type { RevetKey } from "./B06_Section_UI_Cross_Culvert"; import type { StructurePickHandoff } from "../B05_Profile/B05_Profile_UI_Structure_Pick_Session"; /** 기슭막이 조정창이 받는 부재키 — 집수정·배관·본체는 여기서 빠진다. */ const REVET_KEYS = /^(inlet|outlet|own|extra\d+|bextra\d+)$/; interface PickTargets { focusStation: (stationId: string) => void; refreshCard: (chainageM: number) => void; revetSelect: (chainageM: number, key: RevetKey) => void; fordSelect: (chainageM: number, role: "inlet" | "outlet") => void; boxSelect: (chainageM: number, role: "left" | "right") => void; } /** * 넘김값을 화면에 적용한다. 값이 없거나 그 측점이 이 노선에 없으면 아무것도 안 한다. * 카드가 다 선 뒤에 고른다 — 스크롤이 자리를 잡아야 한다. */ export function applyStructurePick( handoff: StructurePickHandoff | null, detail: SectionDetailResponse | null, targets: PickTargets, ): void { if (!handoff) return; // 허용오차는 같은 화면의 다른 대조와 같은 0.05m 다 — 0.01m 로는 3D 가 준 누가거리가 // 소수점 아래에서 조금만 달라도 그 측점을 못 찾고 조용히 끝났다(2026-09-05 진단). const target = detail?.cross_sections.find( (section) => Math.abs(section.chainage_m - handoff.at) < 0.05, ); if (!target) return; // 조정창은 앞칸(측 이름)만 본다 — 뒤칸은 3D 강조를 부재 하나로 좁히는 몫이다. const key = handoff.key?.split(":")[0]; requestAnimationFrame(() => { targets.focusStation(target.station_id); if (!key || key === "body") return; if (target.ford) { if (key !== "inlet" && key !== "outlet") return; targets.fordSelect(target.chainage_m, key); } else if (target.box) { if (key !== "left" && key !== "right") return; targets.boxSelect(target.chainage_m, key); } else { if (!REVET_KEYS.test(key)) return; targets.revetSelect(target.chainage_m, key as RevetKey); } targets.refreshCard(target.chainage_m); }); }