Files
Aislo/A00_Common/map/map_terrain_chip.ts
T

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 };
}