Files
Aislo/A00_Common/design/design_structure_ford_calc.ts
T
eomsangdonandClaude Opus 5.5 0c7f71d103 feat(b05): 물넘이포장 도수로/돌붙임 길이 ↔ 면적 — 넣음 = 월류 폭 × 길이 · 비움 = 기본값 (287-1)
- syncChuteArea(design_structure_ford_calc) — 길이 · 월류 폭 칸이 바뀌면 면적 칸을 다시 채움
- 폭 = 띠가 도로 방향으로 걸치는 월류 폭(비면 물넘이 기본 폭) · 그림은 286-3 대로(길이 = 그 길이 · 비움 = 원지반까지)
- 시험 test_287 새로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TteK8mfYZetk5P3bEZkyVZ
2026-10-12 20:44:14 +09:00

69 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* =============================================================================
* design_structure_ford_calc.ts
* 세월교 명세 계산 — 월류 폭 ↔ 월류 높이 연동(PLAN 52-4).
*
* 높이 = 담당 유역 설계유량을 그 월류 폭으로 넘기는 필요 수심(Manning 개수로 · `fordSection` 그대로).
* 근거: Manning 공식 `resources/knowledge/technical_info/01_임도/03_계산정보/통수단면.md:23~33`
* (KDS 44 40 00 2.7.1~2.7.2) · 조도계수 0.017 = 같은 파일 :59(콘크리트 수로 보통 · 울진 물넘이) ·
* 경사 10 % = 실무 수리계산서 역산값(`config_frontend.FORD_SLOPE` · 지식DB 수치 없음).
* 폭을 바꾸면 높이 칸을 이 값으로 채움 · 사용자는 올려 적을 수 있고 이 값 아래로는 안 받음.
* 높이는 저장되는 입력값 — 서버는 받은 높이로 노면을 내림(`B06_Section_Engine_Culvert._ford_set`) · 재계산 안 함.
* 설계유량이 없으면 null = 손 입력.
* 짝: 자동 배치 새 세월교 빈 높이 = 서버 `B04_PreProcess_Router_Basins.ford_height_m`(같은 풀이 · 65-4) ·
* 거울 시험 test_65_ford_defaults.
* 짝: B08 수리집수면적표 세월교 · 물넘이 월류 높이 = 서버 `B08_Quantity_Engine_Hydro.ford_depth`
* (같은 풀이 · n · S 를 받음) · 거울 시험 test_73_11_b08_hydro_box_ford.
* ========================================================================== */
import { FORD_PAVEMENT_DEFAULT_WIDTH_M } from "@config/config_frontend";
import { fordSection } from "../../B05_Profile/B05_Profile_UI_Drainage_Facility_Fields";
import type { SpecForm } from "./design_structure_form";
import { CHUTE_ITEMS } from "./design_structure_guard";
import type { SpecContainer, SpecItem } from "./design_structure_spec";
/** 월류 폭(m) → 필요 월류 높이(m) · 0.01 m 올림. 유량 · 폭이 없으면 null. */
export function fordHeightM(designFlowM3s: number | null, widthM: number): number | null {
const section = fordSection(designFlowM3s, widthM);
return section ? Math.ceil(section.depthM * 100 - 1e-9) / 100 : null;
}
/** 높이 빈 칸 안내. */
export function fordHeightHint(designFlowM3s: number | null, widthM: number): string {
const need = fordHeightM(designFlowM3s, widthM);
if (need !== null) return `필요 수심 ${need.toFixed(2)} 이상`;
return designFlowM3s ? "월류 폭을 넣으면 셈" : "설계유량 없음 — 수기 입력";
}
/** 도수로 · 돌붙임 면적(㎡ · 287-1) = 폭 × 길이 · 0.01 반올림. */
export function chuteAreaM2(widthM: number, lengthM: number): number {
return Math.round(widthM * lengthM * 100) / 100;
}
/**
* 물넘이 포장 도수로/돌붙임 길이 ↔ 면적(287-1) — 길이를 넣으면 면적 = 폭 × 길이(폭 = 띠가 도로 방향으로
* 걸치는 월류 폭 · 비면 물넘이 기본 폭) · 길이를 비우면 면적 = 칸 기본값 · 월류 폭을 바꾸면 길이가 있을 때만
* 다시 셈. 길이는 그림(사면 따라 그 길이) · 면적은 수량(B08 돌붙임)이 씀.
*/
export function syncChuteArea(
form: Pick<SpecForm, "state" | "setValue">,
c: SpecContainer,
item: SpecItem,
): void {
const byLength = c.id === "chute" && item.id === "length_m";
if (!byLength && !(c.id === "slope" && item.id === "width")) return;
const chute = form.state().chute?.[0];
if (!chute) return;
const length = Number(chute.length_m ?? "");
if (!(chute.length_m ?? "").trim() || !(length > 0)) {
if (byLength)
form.setValue("chute", "area", CHUTE_ITEMS.find((i) => i.id === "area")?.default ?? "");
return;
}
const width = Number(form.state().slope?.[0]?.width ?? "");
form.setValue(
"chute",
"area",
String(chuteAreaM2(width > 0 ? width : FORD_PAVEMENT_DEFAULT_WIDTH_M, length)),
);
}