/* ============================================================================= * B05_Profile_UI_RouteEdit_Terrain.ts * 평면 설계 지형 칩(PLAN 626-1 · 요구 530 · 결정 A④ · D2) — 공용 지형 칩(`map_terrain_chip`)으로 설계 지형 보기 · 바꾸기. * 고를 수 있는 지형 = `/route/terrain-sources`(없는 쪽 막힘) · 바꾸면 확인창 → `POST /route/design-terrain` * (설계 지형 바꿈 · 뒤 단계 모두 다시 셈 · 노선 값 · 초기값 · 추천 저장본 그대로 · 잠금 막) → 초안 비움 → 페이지 다시 세움. * 취소 · 실패 = 칩을 지금 지형으로 되돌림. 옛 길(추천 [적용] 안 지형 고르기 · 509-5) 대신. * 부르는 곳 = `_Chrome`(도구줄 `terrain` 칸) · `_RouteEdit`(지형 읽은 뒤 `load`). * ========================================================================== */ import { clearDrafts } from "../A00_Common/b_page_state"; import { createTerrainChip, TERRAIN_NAMES, type TerrainSource, } from "../A00_Common/map/map_terrain_chip"; import { askConfirm } from "@ui/ui_template_modal"; import { hideLoadingOverlay, showLoadingOverlay, showToast } from "@ui/ui_template_elements"; import { requestJson, type AnalysisTerrain } from "./B05_Profile_Api_Replan"; import { forgetDesignTerrainGrid } from "./B05_Profile_Api_TerrainGrid"; import { rebuildAfterRouteSave } from "./B05_Profile_UI_RouteEdit_Apply"; /** 서버 설계 지형 이름(`las`) ↔ 공용 칩 값(`lidar`). */ const toChip = (terrain: AnalysisTerrain): TerrainSource => (terrain === "las" ? "lidar" : "sheet"); const toServer = (source: TerrainSource): AnalysisTerrain => (source === "lidar" ? "las" : "sheet"); export interface RouteTerrain { root: HTMLElement; /** 지형을 읽음(못 읽음 = null · 칩 숨김). */ load: (sources: { sources: AnalysisTerrain[]; design: AnalysisTerrain } | null) => void; /** 지금 설계 지형. */ design: () => AnalysisTerrain; } export function createRouteTerrain(projectId: string): RouteTerrain { let design: AnalysisTerrain = "las"; let busy = false; const chip = createTerrainChip({ page: "b05", value: toChip(design), have: [], onChange: (value) => void change(toServer(value)), }); chip.root.hidden = true; async function change(next: AnalysisTerrain): Promise { if (busy || next === design) return chip.set(toChip(design)); const ok = await askConfirm({ title: "설계 지형 바꿈", message: `설계 지형을 ${TERRAIN_NAMES[toChip(next)]}(으)로 바꿉니다 — 종단 · 횡단 · 배수 · 토공을 모두 다시 셈합니다. ` + "평면 노선 · 초기값([초기화])은 그대로 · 저장 안 한 고침은 버립니다.", okLabel: "바꿈", }); if (!ok) return chip.set(toChip(design)); busy = true; showLoadingOverlay(); try { await requestJson( `/projects/${projectId}/route/design-terrain`, { method: "POST", body: JSON.stringify({ terrain: next }) }, 600000, ); design = next; clearDrafts(projectId); forgetDesignTerrainGrid(projectId); // 새 지형 격자로(509-2) showToast(`설계 지형을 ${TERRAIN_NAMES[toChip(next)]}(으)로 바꿨습니다.`, "success"); await rebuildAfterRouteSave(projectId); } catch (error) { chip.set(toChip(design)); showToast( `설계 지형을 바꾸지 못했습니다.${error instanceof Error ? ` ${error.message}` : ""}`, "error", ); } finally { busy = false; hideLoadingOverlay(); } } return { root: chip.root, load(sources) { chip.root.hidden = !sources; if (!sources) return; design = sources.design; chip.set(toChip(design)); chip.setHave(sources.sources.map(toChip)); }, design: () => design, }; }