- 잇기 단추 글 「고르기」 → 「선택」(명세 · 정의 그룹 · 종류 단위 줄 공용) - 「지난 정의 값」 상자 모든 종류에서 숨김 — 값은 파일에 그대로 · 코드 남김 - 관 길이 = 보여 주는 칸(손 입력 칸 아님 · 정수 · 횡단 전 「횡단 설계 뒤 셈」) - 유입 집수정 = 길이 · 기준측점 전 · 후 칸 숨김 · 옛 값은 병합이 지킴 - 배관 유출 칸에 읽기 줄(관 길이 · 좌우 자동 자리 안내) 안 옮김 - [흙막이 추가] 없앰 — 흙막이 컨테이너 수 = 유출 「추가 기슭막이(단)」 N(늘 보임 · 줄면 끝에서 빠짐 · 잇기 함께 풂 · 이름 흙막이) - 단 수 소스 = 횡단 세션 값 → 캐시 patch · 종단 보기도 같은 횡단 자료(B05 = B06) - 지형이 단을 못 세워 되돌릴 때 캐시 patch 도 맞춤(옛 수로 돌아가던 흠) - 집계표 선택 컨테이너 이름 짝(서버) 흙막이 · 시험 기대값 · 52-1 · 52-13 화면 시나리오 고침 · 54-1 화면 점검 추가 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVPp2o6Mh2FZJr72yW3ofZ
197 lines
6.5 KiB
TypeScript
197 lines
6.5 KiB
TypeScript
/* =============================================================================
|
|
* design_structure_pipe.ts
|
|
* 횡단배수 › 배관 명세 — 사용자 구조물 표 01(`docs/raw/구조물정의_표/01_횡단배수_배관.md`) 그대로.
|
|
*
|
|
* 컨테이너 다섯: 관(필수) · 관 보호공(유입)(필수) · 관 보호공(유출)(필수) · 흙막이(선택 · 개수 = 유출
|
|
* 「추가 기슭막이(단)」 · 54-1) · 도수로/돌붙임(선택 · 여러 개). 집수정 = 길이 · 전 · 후 없음(54-1).
|
|
* 구조 · 정본 = 이 명세 · 이름만 정의(M02)에서 바꿈.
|
|
* 저장 키 = pipe_points.json 옛 키 그대로(B06 횡단 · B07 · B08 이 읽는 자리) — 흙막이 값은 옛 「기슭막이」
|
|
* (`inlet_type` · `*_revet_*`)에 둠. 새 키 = 집수정 높이 · 선택 컨테이너(`soil_add_{n}_*` · `chute_add_{n}_*`).
|
|
* 정함(PLAN 52): 유출 형태 = 흙막이 6가지 · 도수로/돌붙임 = 구조만 · 길이 = 전 + 후 맞물림.
|
|
* 계산(관 길이 · 높이 안내)은 `design_structure_pipe_calc`.
|
|
* import = 같은 폴더 명세뿐 — 시험이 이 폴더 파일만 옮겨 돌림.
|
|
* ========================================================================== */
|
|
|
|
import type { SpecChoice, SpecItem, StructureSpec } from "./design_structure_spec";
|
|
import { BOX_SPEC } from "./design_structure_box";
|
|
import { FORD_SPEC } from "./design_structure_ford";
|
|
import { FORD_PAVEMENT_SPEC } from "./design_structure_ford_pavement";
|
|
import { ETC_SPEC, PAVEMENT_SPEC } from "./design_structure_road";
|
|
|
|
const SOIL = "기슭막이"; // 저장 값(옛 키 그대로) — 화면 이름은 흙막이
|
|
const BASIN = "집수정";
|
|
const SOIL_FORMS: SpecChoice[] = [
|
|
{ value: "돌쌓기(찰)", label: "돌 쌓기(찰)" },
|
|
{ value: "돌쌓기(메)", label: "돌 쌓기(메)" },
|
|
{ value: "콘크리트", label: "콘크리트" },
|
|
{ value: "돌망태", label: "돌망태" },
|
|
{ value: "통나무·목재틀", label: "통나무/목재틀" },
|
|
{ value: "바자", label: "바자" },
|
|
];
|
|
const BASIN_FORMS: SpecChoice[] = [
|
|
{ value: "I", label: "I형" },
|
|
{ value: "L", label: "L형" },
|
|
{ value: "U", label: "ㄷ형" },
|
|
];
|
|
|
|
/** 형태 · 길이 · 높이 · 전 · 후 — 필수 보호공은 구조 갈래마다 옛 키 · 선택 흙막이는 인스턴스 키. */
|
|
function guardItems(keys?: Record<string, Record<string, string>>): SpecItem[] {
|
|
const by = (field: string, choices?: Record<string, SpecChoice[]>) =>
|
|
keys
|
|
? {
|
|
item: "structure",
|
|
map: Object.fromEntries(
|
|
// 키 없는 갈래 = 그 구조에 없는 칸(집수정 길이 · 전 · 후) — 가림
|
|
Object.entries(keys)
|
|
.filter(([, k]) => k[field])
|
|
.map(([structure, k]) => [
|
|
structure,
|
|
{ key: k[field], choices: choices?.[structure] },
|
|
]),
|
|
),
|
|
}
|
|
: undefined;
|
|
return [
|
|
{
|
|
id: "form",
|
|
label: "형태",
|
|
kind: "select",
|
|
choices: SOIL_FORMS,
|
|
by: by("form", { [BASIN]: BASIN_FORMS, [SOIL]: SOIL_FORMS }),
|
|
},
|
|
{ id: "length", label: "길이 (m)", kind: "number", split: "length", step: 1, by: by("length") },
|
|
{ id: "height", label: "높이 (m)", kind: "number", step: 0.1, by: by("height") },
|
|
{
|
|
id: "before",
|
|
label: "기준측점 전 (m)",
|
|
kind: "number",
|
|
split: "before",
|
|
step: 0.5,
|
|
by: by("before"),
|
|
},
|
|
{
|
|
id: "after",
|
|
label: "기준측점 후 (m)",
|
|
kind: "number",
|
|
split: "after",
|
|
step: 0.5,
|
|
by: by("after"),
|
|
},
|
|
];
|
|
}
|
|
|
|
const revetKeys = (side: "inlet" | "outlet"): Record<string, string> => ({
|
|
form: `${side}_revet_form`,
|
|
length: `${side}_revet_length_m`,
|
|
height: `${side}_revet_height_m`,
|
|
before: `${side}_revet_before_m`,
|
|
after: `${side}_revet_after_m`,
|
|
});
|
|
|
|
export const PIPE_SPEC: StructureSpec = {
|
|
typeId: "pipe",
|
|
containers: [
|
|
{
|
|
id: "pipe",
|
|
title: "관",
|
|
required: true,
|
|
link: "grv6lny", // 정의 그룹 「관」(46장) — 집계표 잇기 자리 그대로
|
|
items: [
|
|
{
|
|
id: "diameter",
|
|
label: "관경",
|
|
kind: "select",
|
|
key: "pipe_diameter_mm",
|
|
asNumber: true,
|
|
choices: ["800", "1000", "1200", "1500"].map((v) => ({ value: v, label: v })),
|
|
},
|
|
{ id: "length", label: "관 길이 (m)", kind: "auto" },
|
|
],
|
|
},
|
|
{
|
|
id: "inlet",
|
|
title: "관 보호공 (유입)",
|
|
required: true,
|
|
link: "gnbf9m9",
|
|
items: [
|
|
{
|
|
id: "structure",
|
|
label: "구조",
|
|
kind: "select",
|
|
key: "inlet_type",
|
|
choices: [
|
|
{ value: BASIN, label: "집수정" },
|
|
{ value: SOIL, label: "흙막이", also: { inlet_structure: "revet" } },
|
|
],
|
|
},
|
|
...guardItems({
|
|
[BASIN]: { form: "inlet_structure", height: "inlet_basin_height_m" },
|
|
[SOIL]: revetKeys("inlet"),
|
|
}),
|
|
],
|
|
},
|
|
{
|
|
id: "outlet",
|
|
title: "관 보호공 (유출)",
|
|
required: true,
|
|
link: "g9lq9uk",
|
|
items: [
|
|
{
|
|
id: "structure",
|
|
label: "구조",
|
|
kind: "select",
|
|
key: "outlet_type",
|
|
choices: [{ value: SOIL, label: "흙막이" }],
|
|
},
|
|
...guardItems({ [SOIL]: revetKeys("outlet") }),
|
|
],
|
|
},
|
|
{
|
|
id: "soil_add",
|
|
title: "흙막이",
|
|
required: false,
|
|
prefix: "soil_add",
|
|
link: "gsoiladd",
|
|
items: [
|
|
{
|
|
id: "structure",
|
|
label: "구조",
|
|
kind: "select",
|
|
choices: [{ value: SOIL, label: "흙막이" }],
|
|
},
|
|
...guardItems(),
|
|
],
|
|
},
|
|
{
|
|
id: "chute_add",
|
|
title: "도수로/돌붙임",
|
|
required: false,
|
|
prefix: "chute_add",
|
|
link: "gchuteadd",
|
|
items: [
|
|
{
|
|
id: "structure",
|
|
label: "구조",
|
|
kind: "select",
|
|
choices: [
|
|
{ value: "도수로", label: "도수로" },
|
|
{ value: "돌붙임", label: "돌붙임" },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
// 표 01 에 없는 옛 칸 — 화면에서 빼고 값은 남김(지난 정의 값)
|
|
retired: ["pipe_kind", "wing_wall_type", "inlet_basin_form", "inlet_basin_material"],
|
|
};
|
|
|
|
/** 명세로 그리는 종류 — 종류 키 → 명세(표가 오는 대로 더함). */
|
|
export const STRUCTURE_SPECS: Readonly<Record<string, StructureSpec>> = {
|
|
pipe: PIPE_SPEC,
|
|
box_culvert: BOX_SPEC,
|
|
ford_bridge: FORD_SPEC,
|
|
ford_pavement: FORD_PAVEMENT_SPEC,
|
|
pavement_concrete: PAVEMENT_SPEC,
|
|
etc: ETC_SPEC,
|
|
};
|