feat(B06): 지반유형을 「토사」 토글 하나로 — 끄면 암(기본), 표준 패널에 각도 병기

사용자 확정(2026-09-07): 「리핑암과 발파암 버튼을 삭제하면서 구분의 의미가 없어졌어. …
토사버튼만 존재하고 이값은 활성화/비활성화로 반영(기본값은 비활성화) / 비활성화 상태에서는
암경계선이 나오고 암경계선 아래는 사용자가 지정한 암 절토각 반영. 이후는 토사 절토 각도를
반영 / 활성화 상태에서는 암반이 없으니 절토는 토사 절토 각도로만 구현」

**화면** — 카드 제목줄의 지반유형 버튼 셋(토사·리핑암·발파암)이 **「토사」 단추 하나**가 됨.
색으로 켜짐/꺼짐을 보이고 **기본은 꺼짐(암)**. 측구 토글과 같은 꼴임.

실화면 확인(용화 5601e828 · route 169 · 측점 1+0.0):
· **암**(꺼짐) — 암 경계선·암 절토각 칸 보임, 절토 토사 1.99 + 암 1.91 = **3.90㎡**
· **토사**(켜짐) — 두 칸 사라짐, 절토 **전량 토사 7.20㎡**(토사 경사가 더 완만해 더 팜)
· 다시 끄면 3.90㎡ 로 정확히 원복

**저장값은 종전 그대로** — 꺼짐 = `ripping_rock`, 켜짐 = `soil`. 옛 자료의 `blasting_rock`
도 「암」으로 읽힘. ⚠ 유토곡선·수량은 이제 암을 **한 종류(리핑암)**로 잡음 — 연암:경암 ·
발파암:리핑암을 가르는 것은 **설계내역에서 설계자가 비율로**(계획서 8-1).

표준 횡단면 설정의 절토·성토 경사 칸에 **각도를 함께 보임**(툴팁) — 카드가 도(°)로 받으므로
두 자리의 말이 갈리지 않게 함. 1:0.4 = 68.2° · 1:1.0 = 45° · 1:1.5 = 33.7°.

⑤ **표준을 바꿔도 개별로 고친 측점은 그대로**를 실화면에서 확인 —
1번 카드에 40° 를 넣고 표준 암 절토경사를 0.4 → 0.8 로 바꿔 [전체 측점 반영]:
· 1번(사용자 값) **40.0° 유지 · 암 절토 5.66㎡ 그대로**
· 2번(값 없음) 68.2° → **51.3°**(=1:0.8) · 암 절토 2.61 → 4.01㎡
· 표준을 되돌리자 둘 다 원상 복귀

시험 3건 더 — 토글 하나인지 · 기본이 암인지 · 옛 발파암 자료도 암 기하로 읽히는지.
전체 **486 passed · 17 skipped**.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 18:05:46 +09:00
co-authored by Claude Opus 5
parent 6b9c115baa
commit e7695c678f
2 changed files with 47 additions and 11 deletions
+33 -11
View File
@@ -69,11 +69,19 @@ function L(key: keyof typeof ui_locales): string {
return ui_locales[key][currentLanguageIndex];
}
const GROUND_OPTIONS: Array<[GroundType, keyof typeof ui_locales]> = [
["soil", "B06_Design_Ground_Soil"],
["ripping_rock", "B06_Design_Ground_Ripping"],
["blasting_rock", "B06_Design_Ground_Blasting"],
];
/**
* 지반유형은 **「토사」 토글 하나**다(2026-09-07 사용자 확정) — 켜면 토사, **끄면 암**(기본).
*
* 사용자 원문 — 「리핑암과 발파암 버튼을 삭제하면서 구분의 의미가 없어졌어. … 토사버튼만
* 존재하고 이값은 활성화/비활성화로 반영(기본값은 비활성화)」. 까닭은 **암반 지정·범위가
* 실무에서 애매해** 측점마다 암질을 못 박는 것이 오히려 틀리기 때문이고, 연암:경암 ·
* 발파암:리핑암은 **설계내역에서 설계자가 비율로** 넣기로 했다(계획서 8-1).
*
* ⚠ 저장값은 종전 그대로 쓴다 — 끔 = `ripping_rock`, 켬 = `soil`. 옛 자료의 `blasting_rock`
* 도 「암(끔)」으로 읽힌다. 유토곡선·수량은 암을 한 종류(리핑암)로 잡으며, 갈라 넣는 것은
* 설계내역 몫이다.
*/
const GROUND_ROCK_DEFAULT: GroundType = "ripping_rock";
const MODE_OPTIONS: Array<[SectionMode, keyof typeof ui_locales]> = [
["left_cut", "B06_Design_Mode_LeftCut"],
["right_cut", "B06_Design_Mode_RightCut"],
@@ -321,7 +329,8 @@ export function buildDesignControls(
twoStage: boolean;
ditchEnabled: boolean | null;
} = {
ground: design?.ground_type ?? "soil",
// 설계가 아직 없는 측점의 기본은 **암**이다(2026-09-07 사용자: 「기본값은 비활성화」).
ground: design?.ground_type ?? GROUND_ROCK_DEFAULT,
mode: design?.section_mode ?? (section.uphill_side === "right" ? "right_cut" : "left_cut"),
ditch: design?.ditch_side ?? null,
ditchType: design?.ditch_type ?? "standard",
@@ -353,11 +362,24 @@ export function buildDesignControls(
});
};
// 지반유형: 제목행 배치용으로 분리 반환(D-6). 라벨 삭제(3번) — 버튼만.
const groundSegment = segment("", GROUND_OPTIONS, state.ground, (value) => {
state.ground = value;
emit();
});
// 지반유형: 제목행 배치용으로 분리 반환(D-6). 「토사」 토글 하나 — 끄면 암이다(2026-09-07).
// 버튼명은 「토사」로 고정하고 **켜짐/꺼짐(색)**으로 상태를 보인다 — 측구 토글과 같은 꼴
// (사용자 원문: 「토사버튼만 존재하고 이값은 활성화/비활성화로 반영」).
const groundToggle = toggle(
"",
state.ground === "soil",
L("B06_Design_Ground_Soil"),
L("B06_Design_Ground_Soil"),
() => {
state.ground = state.ground === "soil" ? GROUND_ROCK_DEFAULT : "soil";
emit();
},
);
groundToggle.button.title =
state.ground === "soil"
? "토사 — 암반이 없어 절토는 토사 경사 하나로만 그린다. 누르면 암으로 바뀐다."
: "암 — 암 경계선이 서고 그 아래는 암 절토각, 위는 토사 경사로 그린다. 누르면 토사로 바뀐다.";
const groundSegment = groundToggle.wrap;
groundSegment.classList.add("b06-design__seg--header");
// 단면 유형은 지형에서 자동 판정되며(D-2), 제목행 pill로 표시한다(E-3, Cross_View에서 생성).
// 아래 옵션은 상시 노출하되 선행 조건 미충족 시 비활성 처리한다(E-6).
@@ -27,6 +27,7 @@ import {
import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale";
import { createButton, createInputField, createSelectField } from "@ui/ui_template_elements";
import { buildStandardDiagram } from "./B06_Section_UI_Standard_Diagram";
import { ratioToDegrees } from "./B06_Section_UI_Cross_CutSlope";
import {
getCompanyStandard,
listCompanyStandards,
@@ -303,6 +304,19 @@ export function createStandardPanel(
});
field.input.step = "0.1";
field.input.min = "0";
// 경사 칸은 **각도도 함께 보인다** — 카드의 개별 절토각 칸이 도(°)로 받으므로 두 자리의
// 말이 갈리지 않게 한다(2026-09-07). 1:0.4 = 68.2° · 1:1.0 = 45° · 1:1.5 = 33.7°.
if (spec.label === "B06_Std_Field_CutSlope" || spec.label === "B06_Std_Field_FillSlope") {
const showAngle = (): void => {
const ratio = Number(field.input.value);
field.input.title =
Number.isFinite(ratio) && ratio > 0
? `1:${ratio} = ${ratioToDegrees(ratio).toFixed(1)}° (횡단 카드의 각도 칸과 같은 값)`
: "";
};
showAngle();
field.input.addEventListener("input", showAngle);
}
grid.append(field.root);
};