feat(B06): 곡선부 확폭에 앞뒤 10m 테이퍼 추가

별표2 는 확폭량 표만 주고 붙이는 방식이 없어, 곡선 시·종점에서 폭이 뚝 끊겼다.
곡선 앞뒤 CURVE_WIDENING_TAPER_M(10m) 구간에서 0 → W 로 잇는다.

- 측점 생성 때 확폭량을 한 번에 계산해 curve_widening_m 으로 저장. 테이퍼는
  이웃 측점을 봐야 하므로 측점 단위 계산으로는 낼 수 없다.
- 설계 엔진(파이썬·TS 짝)이 저장된 확폭량을 우선 쓰고, 없으면 반경 표값으로
  되돌아간다 — 옛 저장분도 그대로 돈다.

검증: pytest 389 passed(테이퍼 경계값 테스트 2건 추가), tsc --noEmit 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-06 15:02:58 +09:00
co-authored by Claude Opus 5
parent dd61754705
commit bdbefd9472
6 changed files with 87 additions and 5 deletions
+16 -4
View File
@@ -41,9 +41,10 @@ from config.config_system import (
SECTION_GROUND_TYPE_PRESET,
SECTION_MODES,
STANDARD_CROSS_SECTION,
curve_widening_m,
)
from config.config_system import (
curve_widening_m as _curve_widening_m,
)
# 사면이 원지반과 만났다고 볼 높이차(m). 이보다 크면 샘플 끝에서 잘린 것으로 본다.
_SLOPE_CLOSE_TOLERANCE_M = 0.01
@@ -463,10 +464,12 @@ def curve_widening_args(section: dict[str, Any] | None) -> dict[str, Any]:
옛 저장분에는 두 값이 없어 확폭 없이 예전과 같은 단면이 나온다.
"""
if not isinstance(section, dict):
return {"plan_radius_m": None, "curve_outer_side": None}
return {"plan_radius_m": None, "curve_outer_side": None, "curve_widening_m": None}
return {
"plan_radius_m": section.get("plan_radius_m"),
"curve_outer_side": section.get("curve_outer_side"),
# 곡선 앞뒤 테이퍼가 얹힌 값 — 있으면 반경 표값 대신 이걸 쓴다(2026-09-06).
"curve_widening_m": section.get("curve_widening_m"),
}
@@ -486,6 +489,7 @@ def compute_cross_design(
surface_drop_m: float = 0.0,
plan_radius_m: float | None = None,
curve_outer_side: str | None = None,
curve_widening_m: float | None = None,
) -> dict[str, Any]:
"""측점 하나의 표준횡단 설계선과 절·성토 단면적을 계산한다.
@@ -544,7 +548,15 @@ def compute_cross_design(
)
soil_cut_ratio = _resolve_group("soil", standard)["cut_slope_ratio"]
# 곡선부 확폭 — 표는 하한이고, 확폭을 더한 유효너비가 법정 상한(5m)을 넘지 않게 자른다.
widening = curve_widening_m(plan_radius_m) if curve_outer_side in ("left", "right") else 0.0
# 저장된 확폭량(테이퍼 포함)이 있으면 그것을 쓰고, 없으면 반경 표값으로 되돌아간다.
if curve_outer_side in ("left", "right"):
widening = (
float(curve_widening_m)
if isinstance(curve_widening_m, (int, float))
else _curve_widening_m(plan_radius_m)
)
else:
widening = 0.0
if widening > 0.0:
room = max(CURVE_WIDENING_MAX_WIDTH_M - group["road_width_m"], 0.0)
widening = min(widening, room)