Files
Aislo/B06_Section/B06_Section_Engine_Design_Node.py
T
eomsangdonandClaude Opus 5.5 3a64f9a812 feat(472-4 ② 횡단 짝 모으기): [저장] · [확정] 횡단 설계선 · 면적 · 소단 구간을 Node 입구 한 갈래로(C1 · C2 · C4 · X3 풀림)
- Router_Design enforce 셋 · 넓힘 뒤 설계 — 파이썬은 입력 조립만 · 측점 묶음을 Node 한 번(B06_Section_Engine_Design_Node · cross.design) · Node 못 부르면 파이썬 짝
- 소단 구간 셈을 화면 파일에서 common_util_berm_spans.ts 로 · 서버도 같은 TS(cross.berm_spans) · Persist 가 다시 내보냄
- 값: 고정 자료 기준값 0 차(면적 · 계획고 · 누가토량 −17,570.7) · 설계선 점 13 곳 1e-4 m(반올림 동점 · 브레인 승인) — 기준값 시험에 판정 더함
- 시험: compute_cross_design 갈아 끼우던 시험 다섯을 묶음 자리로(까닭: [저장] 다시 셈이 묶음으로 부름) · 소단 글 시험 자리 옮김
- 등록부 · 위키 계산 목록 · B06 지침 줄

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 09:21:42 +09:00

105 lines
4.5 KiB
Python

"""횡단 설계선 · 면적 · 소단 구간을 서버 Node 입구로(PLAN 472-4 ② · 등록부 `cross.design` ·
`cross.berm_spans`) — 브라우저와 같은 TS(`common_util_cross_design` · `common_util_berm_spans`).
파이썬은 입력 조립만 — 측점마다 `compute_cross_design` 키를 모아 Node 한 번에 보냄.
Node 를 못 부르면 파이썬 짝으로(거울 시험 `test_b06_cross_design_mirror` · `test_272_berm_source` ·
알려진 차 = 설계선 점 반올림 동점 1e-4 m — 파이썬 round 짝수 쪽 · TS 위쪽).
"""
from __future__ import annotations
import logging
from pathlib import Path
from typing import Any
from B06_Section.B06_Section_Engine_Design import _resolve_group, compute_cross_design
from common_util.common_util_calc_runner import run_calc
logger = logging.getLogger(__name__)
# 한 측점 입력 = (지반 표본, 계획고, `compute_cross_design` 키 — standard 뺌)
DesignJob = tuple[list[dict[str, Any]], float | None, dict[str, Any]]
def full_standard(standard: dict[str, Any] | None) -> dict[str, Any]:
"""config 기본값 위에 저장분을 덮은 표준 횡단 한 벌 — TS 는 config 를 모름(입력으로 받음)."""
out: dict[str, Any] = {}
for key in ("soil", "rock", "paved"):
g = _resolve_group(key, standard)
out[key] = {
"road_width_m": g["road_width_m"],
"shoulder_left_m": g["shoulder_left_m"],
"shoulder_right_m": g["shoulder_right_m"],
"ditch": {
"top_width_m": g["ditch_top_width_m"],
"bottom_width_m": g["ditch_bottom_width_m"],
"depth_m": g["ditch_depth_m"],
},
"ditch_l_type": {"width_m": g["l_ditch_width_m"], "depth_m": g["l_ditch_depth_m"]},
"cross_slope_pct": {"min": g["cross_slope_pct"]},
"fill_slope_ratio": g["fill_slope_ratio"],
"cut_slope_ratio": g["cut_slope_ratio"],
"pavement_thickness_m": g["pavement_thickness_m"],
}
return out
def _python(job: DesignJob, standard: dict[str, Any] | None) -> dict[str, Any] | None:
samples, elevation, options = job
try:
return compute_cross_design(samples, elevation, standard=standard, **options)
except (ValueError, KeyError):
return None
def compute_cross_designs(
jobs: list[DesignJob], standard: dict[str, Any] | None
) -> list[dict[str, Any] | None]:
"""측점 묶음 횡단 설계 — 차례 그대로 결과 · None = 못 세움(파이썬 ValueError 자리)."""
if not jobs:
return []
stations = [
{
"samples": samples,
"design_elevation_m": elevation,
"options": {
key: (value._asdict() if key == "berm" and value is not None else value)
for key, value in options.items()
},
}
for samples, elevation, options in jobs
]
results = run_calc(
["cross.design"],
{"cross_design": {"standard": full_standard(standard), "stations": stations}},
)
if results is None:
logger.warning("Node 횡단 설계 실패 — 파이썬 짝으로 셈(%d 측점)", len(jobs))
return [_python(job, standard) for job in jobs]
return [None if "error" in row else row for row in results["cross.design"]]
def berm_specs_at(
project_root: Path, chainages: list[float]
) -> list[dict[str, float] | None] | None:
"""측점마다 소단 제원(구조물 정본 구간) · None = 정본을 못 읽음(부르는 쪽이 저장분 그대로)."""
from B05_Profile.B05_Profile_Structures_Repository import load_structures
from B06_Section.B06_Section_Engine_Structures_Wall import berm_span_at, load_berm_spans
try:
structures = [
item.model_dump(include={"type_id", "start_m", "end_m", "chainage_m", "options"})
for item in load_structures(str(project_root))[1]
]
except Exception: # noqa: BLE001 — 정본을 못 읽으면 저장분으로 물러섬
logger.exception("B06 소단 구간을 읽지 못했습니다 (저장분 소단을 씀)")
return None
results = run_calc(
["cross.berm_spans"], {"berm": {"structures": structures, "chainages": chainages}}
)
if results is not None:
return results["cross.berm_spans"]["at"]
logger.warning("Node 소단 구간 실패 — 파이썬 짝으로 셈")
spans = load_berm_spans(project_root)
return None if spans is None else [berm_span_at(spans, c) for c in chainages]