feat(b06): 물넘이포장 자리 횡단 = 측구 없음 · 노면은 표고 낮은 쪽으로 기움 (286-2)
- 설계 계산 ford_paved(파이썬) · fordPaved(TS 짝) — 물넘이 범위 안 측점은 측구가 안 섬(사용자 측구 선택보다 먼저) - 서버 정본 — ford_pavement_ranges 로 기본 설계 · [저장] 재계산 · 포장 범위 맞춤이 판정 · 저장분 재계산은 되실은 값을 이음 - 화면 — 계획선 편집 재계산이 얹힌 물넘이 제원으로 같은 판정 - 노면 기울기 — 유입 = 설계선 양 끝 표고가 높은 쪽(같으면 단면유형) · 경사각도만큼 낮은 쪽(유출)으로 · 도수로 띠도 같은 쪽 - 시험 test_286_1 · 횡단 설계 거울에 물넘이 갈래 · 도수로 띠 시험 기대값 새 규칙으로 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TteK8mfYZetk5P3bEZkyVZ
This commit is contained in:
@@ -77,12 +77,20 @@ def pavement_ranges(project_root: Path) -> list[tuple[float, float]]:
|
||||
ranges.append((min(float(start), float(end)), max(float(start), float(end))))
|
||||
except Exception: # noqa: BLE001 — 정본을 못 읽어도 설계 계산은 이어 간다
|
||||
logger.exception("B06 포장 구간을 읽지 못했습니다 (사용자 지정 없음으로 본다)")
|
||||
for chainage, spec in load_culvert_sets(project_root).items():
|
||||
if spec.get("type") != "ford_pavement":
|
||||
continue
|
||||
half = float(spec.get("span_m") or 0.0) / 2.0
|
||||
ranges.append((chainage - half, chainage + half))
|
||||
return ranges
|
||||
return ranges + ford_pavement_ranges(project_root)
|
||||
|
||||
|
||||
def ford_pavement_ranges(project_root: Path | None) -> list[tuple[float, float]]:
|
||||
"""물넘이포장 범위(기준 ± 월류 폭/2) — 포장 필수 · 측구 없음(286-2). 판정은 `paved_at`."""
|
||||
if project_root is None:
|
||||
return []
|
||||
sets = load_culvert_sets(project_root).items()
|
||||
halves = [
|
||||
(at, float(s.get("span_m") or 0.0) / 2.0)
|
||||
for at, s in sets
|
||||
if s.get("type") == "ford_pavement"
|
||||
]
|
||||
return [(at - half, at + half) for at, half in halves]
|
||||
|
||||
|
||||
def ford_surface_drops(project_root: Path | None) -> list[tuple[float, float]]:
|
||||
@@ -207,6 +215,7 @@ def enforce_pavement_ranges(
|
||||
사용자 조작값(반폭·구조물 조정)은 그대로 승계한다.
|
||||
"""
|
||||
ranges = pavement_ranges(project_root)
|
||||
ford_ranges = ford_pavement_ranges(project_root)
|
||||
ford_drops = ford_surface_drops(project_root)
|
||||
changed = 0
|
||||
for section in cross_sections:
|
||||
@@ -215,7 +224,8 @@ def enforce_pavement_ranges(
|
||||
continue
|
||||
chainage = float(section.get("chainage_m", 0.0))
|
||||
wanted = paved_at(chainage, ranges)
|
||||
if bool(design.get("paved")) == wanted:
|
||||
ford_paved = paved_at(chainage, ford_ranges) # 물넘이 자리 = 측구 없음(286-2)
|
||||
if bool(design.get("paved")) == wanted and bool(design.get("ford_paved")) == ford_paved:
|
||||
continue
|
||||
try:
|
||||
recomputed = compute_cross_design(
|
||||
@@ -238,6 +248,7 @@ def enforce_pavement_ranges(
|
||||
berm=stored_berm(design),
|
||||
**curve_widening_args(section),
|
||||
**stored_shoulder_extend(design), # 노견 확장(139-6)
|
||||
ford_paved=ford_paved,
|
||||
)
|
||||
except (ValueError, KeyError):
|
||||
continue
|
||||
@@ -266,6 +277,7 @@ def enforce_design_lines(
|
||||
from B06_Section.B06_Section_Engine_Structures_Wall import berm_span_at, load_berm_spans
|
||||
|
||||
ford_drops = ford_surface_drops(project_root)
|
||||
ford_ranges = ford_pavement_ranges(project_root)
|
||||
spans = load_berm_spans(project_root)
|
||||
changed = 0
|
||||
for section in cross_sections:
|
||||
@@ -296,6 +308,7 @@ def enforce_design_lines(
|
||||
berm=stored_berm(design),
|
||||
**curve_widening_args(section),
|
||||
**stored_shoulder_extend(design),
|
||||
ford_paved=paved_at(chainage, ford_ranges),
|
||||
)
|
||||
except (ValueError, KeyError):
|
||||
continue
|
||||
@@ -351,6 +364,7 @@ def enforce_ford_surface_drops(
|
||||
berm=stored_berm(design),
|
||||
**curve_widening_args(section),
|
||||
**stored_shoulder_extend(design), # 노견 확장(139-6)
|
||||
ford_paved=bool(design.get("ford_paved")),
|
||||
)
|
||||
except (ValueError, KeyError):
|
||||
continue
|
||||
@@ -423,6 +437,7 @@ def attach_default_designs(
|
||||
modes = default_section_modes(longitudinal)
|
||||
pavement = pavement_suggestions(longitudinal)
|
||||
paved_ranges = pavement_ranges(project_root) if project_root else []
|
||||
ford_ranges = ford_pavement_ranges(project_root)
|
||||
ford_drops = ford_surface_drops(project_root)
|
||||
for section in cross_sections:
|
||||
if section.get("design"):
|
||||
@@ -441,6 +456,7 @@ def attach_default_designs(
|
||||
rock_boundary_offset_m=STANDARD_ROCK_BOUNDARY_DEFAULT_OFFSET_M,
|
||||
surface_drop_m=ford_drop_at(chainage, ford_drops),
|
||||
**curve_widening_args(section),
|
||||
ford_paved=paved_at(chainage, ford_ranges),
|
||||
)
|
||||
design.update(status="provisional", pavement_suggested=suggested)
|
||||
section["design"] = design
|
||||
@@ -501,6 +517,7 @@ def recompute_designs_for_alignment(
|
||||
modes = default_section_modes(longitudinal)
|
||||
pavement = pavement_suggestions(longitudinal)
|
||||
paved_ranges = pavement_ranges(project_root) if project_root else []
|
||||
ford_ranges = ford_pavement_ranges(project_root)
|
||||
ford_drops = ford_surface_drops(project_root)
|
||||
stored_by_chainage = {
|
||||
round(float(record["chainage_m"]), 3): (record.get("design") or {})
|
||||
@@ -559,6 +576,7 @@ def recompute_designs_for_alignment(
|
||||
berm=session_berms.get(key) or stored_berm(stored),
|
||||
**curve_widening_args(section),
|
||||
**stored_shoulder_extend(stored), # 노견 확장(139-6)
|
||||
ford_paved=paved_at(chainage, ford_ranges),
|
||||
)
|
||||
except (ValueError, KeyError):
|
||||
continue
|
||||
@@ -603,6 +621,7 @@ def compute_default_designs(
|
||||
default_modes = default_section_modes(longitudinal)
|
||||
pavement = pavement_suggestions(longitudinal)
|
||||
paved_ranges = pavement_ranges(root)
|
||||
ford_ranges = ford_pavement_ranges(root)
|
||||
ford_drops = ford_surface_drops(root)
|
||||
results: list[tuple[float, dict[str, Any]]] = []
|
||||
for chainage_m in chainages:
|
||||
@@ -642,6 +661,7 @@ def compute_default_designs(
|
||||
surface_drop_m=ford_drop_at(chainage_m, ford_drops),
|
||||
berm=stored_berm(user),
|
||||
**curve_widening_args(cross),
|
||||
ford_paved=paved_at(chainage_m, ford_ranges),
|
||||
)
|
||||
for key in ("berm", "cut_slope_ratio_user"):
|
||||
if user.get(key) is not None:
|
||||
|
||||
Reference in New Issue
Block a user