- 확폭은 노선 곡선표로(후보 · 편집 띠 · [확인]) · 없으면 종전 실측 반경 - 반폭에서 비탈이 안 닫히면 지표면 끝까지 넓힌 샘플로 다시 셈(본 설계 extend_unclosed 와 같은 뜻) - 암반 경계 기본 오프셋(본 설계 기본 설계와 같음) - 균형 목표 = 누가토량 끝값(절토 다짐 − 성토) ±500㎥ · 고른 선은 보간 말고 바로 셈해 λ 를 더 좁힘 - 후보 줄 세우기는 보간값 그대로(빠름) · 화면에 낼 선만 바로 셈 - 추천 창 한 줄: 불균형 % → 누가토량 ±㎥ Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019EMfGERKUg5nMMNQsyVZ2j
60 lines
2.4 KiB
Python
60 lines
2.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""노선 추천 균형 종단 — 본 설계와 같은 횡단 · 누가토량 ±500㎥(PLAN 78).
|
|
|
|
랩탑 메인 노선 271: 추천은 곡선표 확폭 · 비탈 안 닫힘 넓힘을 빼 성토를 4,200㎥ 적게 봄.
|
|
"""
|
|
|
|
import numpy as np
|
|
|
|
from B05_Profile.B05_Profile_Engine_RouteInitial_Profile import (
|
|
CROSS_HALF_M,
|
|
_station_areas,
|
|
_widenings,
|
|
route_profile,
|
|
route_sections,
|
|
)
|
|
from B05_Profile.B05_Profile_Engine_RouteInitial_Search import Terrain
|
|
from config.config_system_design import curve_widening_m
|
|
|
|
|
|
def _steep() -> Terrain:
|
|
# 노선(y = 200) 왼쪽(+y)으로 70 % 내리막 — 성토 비탈(1:1.5)이 ±20 m 안에서 안 닫힘
|
|
x = np.arange(0.0, 202.0, 2.0)
|
|
y = np.arange(120.0, 282.0, 2.0)
|
|
xx, yy = np.meshgrid(x, y)
|
|
z = 100.0 - 0.7 * (yy - 200.0) + 0.02 * xx
|
|
return Terrain(x, y, z, np.ones(xx.shape, dtype=bool))
|
|
|
|
|
|
def test_곡선표가_있으면_그_반경으로_확폭():
|
|
xy = np.array([(0.0, 0.0), (40.0, 0.0), (80.0, 0.0)])
|
|
chain = np.array([0.0, 40.0, 80.0])
|
|
at = np.array([0.0, 20.0, 40.0, 60.0, 80.0])
|
|
table = [{"start": [30.0, 0.0], "apex": [40.0, 1.0], "end": [50.0, 0.0], "radius_m": 12.0}]
|
|
rows = _widenings(xy, chain, at, table)
|
|
assert rows[2]["curve_widening_m"] == curve_widening_m(12.0)
|
|
assert rows[2]["plan_radius_m"] == 12.0
|
|
# 곡선표 없으면 직선(반경 실측 없음) — 확폭 0
|
|
assert all(row["curve_widening_m"] == 0 for row in _widenings(xy, chain, at))
|
|
|
|
|
|
def test_비탈_안_닫히면_넓힌_샘플로_셈():
|
|
at, ground, sections, modes, curves = route_sections([(20.0, 200.0), (180.0, 200.0)], _steep())
|
|
i = len(at) // 2
|
|
samples = sections[i]
|
|
assert max(s["offset_m"] for s in samples) > CROSS_HALF_M # 반폭 밖까지 떠 둠
|
|
narrow = [s for s in samples if abs(s["offset_m"]) <= CROSS_HALF_M]
|
|
high = float(ground[i] + 3.0) # 쌓기 — 내리막 쪽 성토 비탈이 길어짐
|
|
_, _, wide_fill = _station_areas(samples, modes[i], high, curves[i])
|
|
_, _, narrow_fill = _station_areas(narrow, modes[i], high, curves[i])
|
|
assert wide_fill > narrow_fill + 1.0
|
|
|
|
|
|
def test_누가토량_끝값은_허용_안():
|
|
profile = route_profile(
|
|
[(20.0, 200.0), (180.0, 200.0)], _steep(), max_grade=0.14, design_speed=20
|
|
)
|
|
assert profile["exact"] is True
|
|
assert abs(profile["mass_end_m3"]) <= profile["mass_tolerance_m3"] == 500.0
|
|
assert profile["balanced"] is True
|