fix(B05): 노선 추천 창 반입 · 사토 표기를 누가토량(±)으로 바꿈(78)
- 한 줄에서 반입 · 사토 뺌 — 누가토량 +/− 만 - 후보 표 반입 칸 → 누가토량(±) 칸 - 토공 최소 도움말 문구도 누가토량으로 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019EMfGERKUg5nMMNQsyVZ2j
This commit is contained in:
@@ -55,9 +55,9 @@ const LOGIC_HELP: Record<ShownLogic, HelpEntry> = {
|
||||
"후보 중 절토 + 성토 어림 양이 가장 적은 것을 고름",
|
||||
"흙 양 = 계획고를 상한 안으로 맞춘 선과 옆경사 단면(노폭 4m)으로 어림",
|
||||
],
|
||||
when: "토공량 · 사토 처리를 줄여야 할 때",
|
||||
when: "토공량 · 누가토량(±)을 줄여야 할 때",
|
||||
caution: "비탈면 흙은 빠진 어림값 · 연장이 길어지는지 비교값으로 함께 볼 것",
|
||||
profile: "후보마다 균형 종단을 세워 절 + 성 + 반입 + 사토 ㎥ 로 비교",
|
||||
profile: "후보마다 균형 종단을 세워 절토 + 성토 + 누가토량(± 크기) ㎥ 로 비교",
|
||||
},
|
||||
gentle: {
|
||||
summary: "종단기울기가 가장 순한 노선",
|
||||
|
||||
@@ -13,11 +13,9 @@ export interface BalanceProfile {
|
||||
stationsM: number[];
|
||||
groundM: number[];
|
||||
planM: number[];
|
||||
/** 절토(자연) · 성토 · 반입 · 사토 ㎥. */
|
||||
/** 절토(자연) · 성토 ㎥. */
|
||||
cutM3: number;
|
||||
fillM3: number;
|
||||
borrowM3: number;
|
||||
spoilM3: number;
|
||||
/** 누가토량 끝값(절토 다짐 − 성토) · 허용 ±㎥. */
|
||||
massEndM3: number;
|
||||
massToleranceM3: number;
|
||||
@@ -43,7 +41,7 @@ export function parseBalance(raw: unknown): BalanceProfile | null {
|
||||
const stationsM = numbers(p.stations_m);
|
||||
const groundM = numbers(p.ground_m);
|
||||
const planM = numbers(p.plan_m);
|
||||
const need = [p.cut_m3, p.fill_m3, p.borrow_m3, p.spoil_m3, p.max_grade_pct].map(num);
|
||||
const need = [p.cut_m3, p.fill_m3, p.max_grade_pct].map(num);
|
||||
if (stationsM.length < 2 || groundM.length !== stationsM.length) return null;
|
||||
if (planM.length !== stationsM.length || need.some((value) => value === null)) return null;
|
||||
return {
|
||||
@@ -52,8 +50,6 @@ export function parseBalance(raw: unknown): BalanceProfile | null {
|
||||
planM,
|
||||
cutM3: num(p.cut_m3)!,
|
||||
fillM3: num(p.fill_m3)!,
|
||||
borrowM3: num(p.borrow_m3)!,
|
||||
spoilM3: num(p.spoil_m3)!,
|
||||
massEndM3: num(p.mass_end_m3) ?? 0,
|
||||
massToleranceM3: num(p.mass_tolerance_m3) ?? 500,
|
||||
maxGradePct: num(p.max_grade_pct)!,
|
||||
@@ -68,12 +64,11 @@ const m3 = (value: number): string => `${Math.round(value).toLocaleString("ko-KR
|
||||
const pct = (value: number): string => `${value.toFixed(1)}%`;
|
||||
const signedM3 = (value: number): string => `${value > 0 ? "+" : ""}${m3(value)}`;
|
||||
|
||||
/** 한 줄 — 「균형 종단: 절 7,646 · 성 7,944 · 반입 0 · 사토 848㎥ · 누가토량 +212㎥(허용 ±500㎥) · …」. */
|
||||
/** 한 줄 — 「균형 종단: 절 7,646 · 성 7,944㎥ · 누가토량 +212㎥(허용 ±500㎥) · …」. */
|
||||
export function balanceLine(balance: BalanceProfile | null): string {
|
||||
if (!balance) return "";
|
||||
const parts = [
|
||||
`균형 종단: 절 ${m3(balance.cutM3)} · 성 ${m3(balance.fillM3)}`,
|
||||
`반입 ${m3(balance.borrowM3)} · 사토 ${m3(balance.spoilM3)}`,
|
||||
`누가토량 ${signedM3(balance.massEndM3)}(허용 ±${m3(balance.massToleranceM3)})`,
|
||||
`최대 종단경사 ${pct(balance.maxGradePct)}(상한 ${pct(balance.gradeLimitPct)})`,
|
||||
];
|
||||
@@ -123,17 +118,17 @@ export function profileSvg(
|
||||
<path class="is-plan" d="${planM.length ? path(planM) : ""}" vector-effect="non-scaling-stroke" /></svg>`;
|
||||
}
|
||||
|
||||
/** 이 모달에서 셈한 후보들 — 갈래 이름 · 절 · 성 · 반입 · 최대 종단경사 표. 비면 빈 글. */
|
||||
/** 이 모달에서 셈한 후보들 — 갈래 이름 · 절 · 성 · 누가토량(±) · 최대 종단경사 표. 비면 빈 글. */
|
||||
export function candidatesTable(rows: Array<[string, BalanceProfile]>): string {
|
||||
if (!rows.length) return "";
|
||||
const body = rows
|
||||
.map(
|
||||
([name, b]) =>
|
||||
`<tr><th scope="row">${name}</th><td>${m3(b.cutM3)}</td><td>${m3(b.fillM3)}</td>` +
|
||||
`<td>${m3(b.borrowM3)}</td><td>${pct(b.maxGradePct)}</td></tr>`,
|
||||
`<td>${signedM3(b.massEndM3)}</td><td>${pct(b.maxGradePct)}</td></tr>`,
|
||||
)
|
||||
.join("");
|
||||
return `<table><thead><tr><th scope="col">후보</th><th scope="col">절토</th>
|
||||
<th scope="col">성토</th><th scope="col">반입</th><th scope="col">최대 종단경사</th></tr></thead>
|
||||
<th scope="col">성토</th><th scope="col">누가토량</th><th scope="col">최대 종단경사</th></tr></thead>
|
||||
<tbody>${body}</tbody></table>`;
|
||||
}
|
||||
|
||||
@@ -112,12 +112,13 @@ def test_균형_종단은_캐시에_안_남는다() -> None:
|
||||
)
|
||||
assert proc.returncode == 0, proc.stderr
|
||||
result = json.loads(proc.stdout)["balance63"]
|
||||
assert result["parsed"]["borrowM3"] == 0 and result["parsed"]["spoilM3"] == 39.9
|
||||
assert result["parsed"]["planM"] == [100, 101.5, 101]
|
||||
assert "balance" not in result["cached"]
|
||||
assert result["cached"]["metrics"]["cutM3"] is not None # 비교값은 그대로 캐시
|
||||
assert result["missing"] is None and result["broken"] is None
|
||||
assert "반입 0㎥" in result["line"] and "덮개 모자란 관 1/2" in result["line"]
|
||||
assert "반입" not in result["line"] and "사토" not in result["line"]
|
||||
assert "덮개 모자란 관 1/2" in result["line"]
|
||||
assert "누가토량 -40㎥(허용 ±500㎥)" in result["line"]
|
||||
assert result["svg"].count("<path") == 2
|
||||
assert '<th scope="row">토공 최소</th>' in result["table"]
|
||||
assert '<th scope="col">누가토량</th>' in result["table"] and "반입" not in result["table"]
|
||||
|
||||
Reference in New Issue
Block a user