67 lines
2.9 KiB
TypeScript
67 lines
2.9 KiB
TypeScript
/* =============================================================================
|
|
* map_terrain_chip.ts
|
|
* 공용 지도 지형 칩(PLAN 624-2 · 요구 530 · 결정 A④ · A⑤ · D2) — 도구줄 끝 분할 고르기 하나: 수치지형도 · 라이다.
|
|
* 이름 = 예정노선 「분석 지형」 · B05 「설계 지형」(바꾸면 뒤 단계 모두 다시 셈 · 확인창은 B05 몫).
|
|
* 없는 원천 = 막힘 + 까닭 글(D03 라이다 = D 프로젝트에 LAS 올린 뒤 · 624-4).
|
|
* 화면 칩만 — 바꾸는 일(서버 원천 인자 624-1 · B05 설계 지형 바꿈 626-1)은 `onChange` 로 페이지가 붙임.
|
|
* 쓰는 법 = `createTerrainChip({ page: "d03", value: "sheet", have: ["sheet"] })` → `{ root, set, setHave }` · root 를 도구줄 `terrain` 칸에.
|
|
* ========================================================================== */
|
|
|
|
import { createSegment } from "@ui/ui_template_segment";
|
|
import type { MapPage } from "./map_layer_list";
|
|
|
|
/** 서버 겹 길 `terrain=` 값과 같음(624-1 · 빈 값 = 설계 지형). */
|
|
export type TerrainSource = "sheet" | "lidar";
|
|
|
|
export const TERRAIN_NAMES: Record<TerrainSource, string> = {
|
|
sheet: "수치지형도",
|
|
lidar: "라이다",
|
|
};
|
|
|
|
const CAPTION: Record<MapPage, string> = {
|
|
d03: "분석 지형 — 급경사 · 음영 · 0차곡 · 긋기 높이에 쓰는 지형",
|
|
b05: "설계 지형 — 바꾸면 종단 · 횡단 · 배수 · 토공을 모두 다시 셈",
|
|
};
|
|
const MISSING: Record<TerrainSource, string> = {
|
|
sheet: "수치지형도 — 이 프로젝트 범위에 도엽 지형 없음",
|
|
lidar: "라이다 — 올린 LAS 없음",
|
|
};
|
|
|
|
export interface TerrainChip {
|
|
root: HTMLElement;
|
|
/** 고름을 바꿈(onChange 는 안 부름). */
|
|
set: (value: TerrainSource) => void;
|
|
/** 고를 수 있는 원천 — 없는 것은 막힘. */
|
|
setHave: (have: readonly TerrainSource[]) => void;
|
|
}
|
|
|
|
export function createTerrainChip(opts: {
|
|
page: MapPage;
|
|
value: TerrainSource;
|
|
have: readonly TerrainSource[];
|
|
onChange?: (value: TerrainSource) => void;
|
|
}): TerrainChip {
|
|
const sources = Object.keys(TERRAIN_NAMES) as TerrainSource[];
|
|
const segment = createSegment({
|
|
options: sources.map((value) => ({ value, label: TERRAIN_NAMES[value] })),
|
|
value: opts.value,
|
|
size: 32,
|
|
ariaLabel: CAPTION[opts.page],
|
|
onChange: (value) => opts.onChange?.(value as TerrainSource),
|
|
});
|
|
const root = segment.root;
|
|
root.dataset.act = "terrain";
|
|
root.title = CAPTION[opts.page];
|
|
const setHave = (have: readonly TerrainSource[]): void => {
|
|
for (const value of sources) {
|
|
const item = root.querySelector<HTMLButtonElement>(`[data-value="${value}"]`)!;
|
|
item.disabled = !have.includes(value);
|
|
item.title = item.disabled
|
|
? MISSING[value]
|
|
: `${CAPTION[opts.page]} · ${TERRAIN_NAMES[value]}`;
|
|
}
|
|
};
|
|
setHave(opts.have);
|
|
return { root, set: (value) => segment.set(value), setHave };
|
|
}
|