/* ============================================================================= * B05_Profile_UI_Panel_Plan.ts * 종단 보기 왼쪽 「그리기」 칸 자리(PLAN 635-3 · 755-2 · 요구 546 · 589-8 위치 칸 걷음) — 예정노선 키트(`createPlanKit` 「b05」) 칸을 앉힘. * 칸은 페이지가 먼저 세우고 편집기는 노선을 읽은 뒤 섬 → 칸 = 빈 자리(order 1) · 편집기가 `fillPlanPanel` 로 채움. * 늦게 온 쪽이 붙임 · 새 칸 자리(페이지 다시 세움) = 떠난 편집기 칸(문서 밖) 버림 · 비면 자리 숨김. * 좌표 변환(635-5) = 서버(`POST /route/coords` · 사업지 좌표계 pyproj) — 속성 판 경위도 때만 부름. * ========================================================================== */ import { registerPanelSection } from "../A00_Common/design/design_panel"; import { requestJson } from "./B05_Profile_Api_Replan"; type Vertex = [number, number]; let holder: HTMLElement | null = null; let card: HTMLElement | null = null; const attach = (): void => { if (!holder) return; holder.replaceChildren(...(card ? [card] : [])); holder.hidden = !card; }; registerPanelSection({ id: "plan-draw", title: "그리기", views: ["profile"], order: 1, build: () => { holder = document.createElement("div"); holder.className = "b05-route__plan-slot"; if (!card?.isConnected) card = null; // 떠난 편집기 칸 attach(); return holder; }, }); /** 키트 칸을 앉힘(새 편집기가 갈음). */ export function fillPlanPanel(next: HTMLElement | null): void { card = next; attach(); } export interface PlanCoords { /** 사업지 → 경위도 — 받은 점이면 바로 · 처음이면 null 주고 한 번 물음(오면 `onLonLat`). */ lonLat: (x: number, y: number) => Vertex | null; } /** 사업지 → 경위도 서버 변환 · 같은 점은 캐시(끌기 중엔 안 부름 — 판은 고름 · 놓음 때만 그림). */ export function createPlanCoords(projectId: string, onLonLat: () => void): PlanCoords { const ask = (to: "lonlat", point: Vertex): Promise => requestJson<{ points: Vertex[] }>( `/projects/${projectId}/route/coords`, { method: "POST", body: JSON.stringify({ to, points: [point] }) }, 15_000, ).then( (answer) => answer.points[0] ?? null, () => null, ); const known = new Map(); return { lonLat(x, y) { const key = `${x},${y}`; if (known.has(key)) return known.get(key) ?? null; known.set(key, null); // 묻는 중 void ask("lonlat", [x, y]).then((at) => { if (at) known.set(key, at); else known.delete(key); // 실패 = 다음 고름 때 다시 if (at) onLonLat(); }); return null; }, }; }