- 624-3 도구줄 = 공용 표 「b05」 · 아래 줄 = 공용 겹 줄(띠 · 올린 임도망도 숨김 · 처음 = 등고선 · 하천) · 범례 = 공용 legendRows(상태 글판 위) - 노선 띠 300 m 자르기 = B05 자기 칸(등고선 · 하천 · 1 m)만 · 그 밖 겹 = 안 자르는 둘째 GL 칸(맨 밑 · 켠 겹 있을 때만 · GL 만) · 등고선 끔 = 등고 글도 숨김 - 626-1 추천 보기 = 도구줄 아이콘 + 아래 판(영선 · 토공 최소 · 기울기 최소 · 비중 계산 · 끔) — route_recommend 저장본(지금 설계 지형) 선만 · 다시 셈 · 쓰기 없음 - 지형 칩 → 확인창 → 새 POST /route/design-terrain(설계 지형만 바꿈 · 노선 저장 체인 다시 · 노선 · 초기값 · 추천 저장본 그대로 · 잠금 · 실패 되돌림) - 걷음 — 추천 모달(_Recommend · _Help · _Map · CSS) · 좌측 「노선 추천」 칸 · saveRecommendedRoute · UI_RouteReset(서버 as_initial 길 · 시험은 남김) - 부품 상자 — createPickMenu(아이콘 고르기 메뉴 · 판 = body fixed · ✓) - 낡은 시험 고침 · 지움 — 모달 · 좌측 칸 · [적용] 화면 배선을 보던 시험(283 · 346_3 · 349 · 364_4 · 383_1 · 390_5 · 418 · 421 · 421_2 · 476_2 · 509_2 · 509_5 · 551_2 · 600_3 · b05_routeedit_initial · design_view_parity · modal_top · 133_1 · 133_2) · test_508_2 · helper_283 지움(모달 전용) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
92 lines
3.8 KiB
TypeScript
92 lines
3.8 KiB
TypeScript
/* =============================================================================
|
|
* 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<void> {
|
|
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,
|
|
};
|
|
}
|