feat(B07): 표준 횡단면도 — 치수·측구 확대도·암반선 2단

빈 도각이던 표준 횡단면도를 실제 도면으로 만듦.

- 본 그림: B06 좌측 패널 모식도와 같은 배치를 실치수로 그림(1/50). 노폭·노견·
  측구 상단폭·노면 전폭에 치수선(눈금+치수값)을 붙이고, 절토·성토 경사비와
  횡단경사를 표기. 값은 B06 표준 횡단면 설정을 그대로 읽고 없으면 config 기본값.
- 측구 부분 확대도(1/10): 상단폭·저폭·깊이 치수 + 확대 축척 표기.
- 암반 2단 절토: 아래는 암반 경사(1:0.4), 위는 토사 경사(1:1), 갈리는 높이에
  암반선을 파선으로 긋고 각도를 함께 적음.
- 암 L형 측구·포장 횡단경사는 주기(※)로 적음 — 본 그림은 토사 기준.

곁들여: Router_Support 가 700줄을 넘어 재수출 import 를 한 문장으로 합쳐 681줄로
줄임(기능 변화 없음).

검증: 치수값이 STANDARD_CROSS_SECTION 과 일치(500·3000·500·900·4000), 확대도
900·300·300 + S=1/10, 2단 절토선 꺾임점 1개, 콘텐츠 358.2x172.6 mm ≤ A1 작도영역.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-04 19:09:06 +09:00
co-authored by Claude Opus 5
parent 18c174036b
commit 02bd45bf3c
7 changed files with 646 additions and 59 deletions
@@ -47,66 +47,36 @@ from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import (
plan_cross_sheets,
section_block_size,
)
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Standard import (
STANDARD_LABEL,
build_standard_cross_drawing,
)
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Table import (
QUANTITY_VALUE_KEYS,
)
from B07_DesignDetail.B07_DesignDetail_Engine_Template import add_title_fields
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
_BASIN_MAX_DISTANCE_M as _BASIN_MAX_DISTANCE_M,
)
# 유역도 배경·파일 입출력 조각은 700줄 제한으로 떼어냈다(2026-09-04).
# 여기서 그대로 다시 내보내 호출부(`B07_DesignDetail_Router.py`)의 import 경로는 불변이다.
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
CONTOUR_FILE as CONTOUR_FILE,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
LANDUSE_ID as LANDUSE_ID,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
LIDAR_ID as LIDAR_ID,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
PLAN_ID as PLAN_ID,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
STREAM_FILE as STREAM_FILE,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
_basins_crs as _basins_crs,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
_clip_segment as _clip_segment,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
_geojson_features as _geojson_features,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
_geojson_payload as _geojson_payload,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
_geometry_lines as _geometry_lines,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
_too_far_from_route as _too_far_from_route,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
clip_line_to_box as clip_line_to_box,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
landuse_source as landuse_source,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
lidar_source as lidar_source,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
plan_source as plan_source,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
plan_stations as plan_stations,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import (
watershed_source as watershed_source,
from B07_DesignDetail.B07_DesignDetail_Router_Support_Basin import ( # noqa: F401
_BASIN_MAX_DISTANCE_M,
CONTOUR_FILE,
LANDUSE_ID,
LIDAR_ID,
PLAN_ID,
STREAM_FILE,
_basins_crs,
_clip_segment,
_geojson_features,
_geojson_payload,
_geometry_lines,
_too_far_from_route,
clip_line_to_box,
landuse_source,
lidar_source,
plan_source,
plan_stations,
watershed_source,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Io import (
_cross_files,
@@ -132,13 +102,12 @@ _LONG_ID = re.compile(r"^longitudinal(?:_(\d+))?$")
MASS_HAUL_ID = "mass_haul"
WATERSHED_ID = "watershed"
COVER_ID = "cover"
# 표준 횡단면도 — 노선 자료가 아니라 B06 표준 횡단면 설정값으로 그리는 한 장.
CROSS_STANDARD_ID = "cross_standard"
# 아직 내용을 만들지 않은 도면 — 도각만 실어 연다(2026-09-01 사용자 지시).
# 화면 순서(DRAWING_GROUPS)와 같은 이름을 쓴다.
BLANK_DRAWINGS: tuple[tuple[str, str], ...] = (
("blank_cross_standard", "표준 횡단면도"),
("blank_standard", "표준도"),
)
BLANK_DRAWINGS: tuple[tuple[str, str], ...] = (("blank_standard", "표준도"),)
BLANK_LABELS: dict[str, str] = dict(BLANK_DRAWINGS)
@@ -224,6 +193,7 @@ def _drawing_list(
# 노선 전장 1장짜리 도면 — 자료가 없으면 여는 시점에 404로 알린다(목록에는 항상 둔다).
for drawing_id, kind, label in (
(COVER_ID, "cover", "표지"),
(CROSS_STANDARD_ID, "cross_standard", STANDARD_LABEL),
(MASS_HAUL_ID, "mass_haul", "토적도(유토곡선)"),
(WATERSHED_ID, "watershed", "유역도(배수 유역도)"),
):
@@ -449,7 +419,7 @@ def _read_drawing(
# 포맷 버전이 다르면(테이블·레이어 구성 변경 전 저장본) 캐시를 버리고
# 아래에서 원본 기준으로 재생성한다. 확정 상태도 무효로 응답해 재확정 유도.
if saved.get("format") == DRAWING_FORMAT:
if drawing_id in (COVER_ID, MASS_HAUL_ID, WATERSHED_ID):
if drawing_id in (COVER_ID, MASS_HAUL_ID, WATERSHED_ID, CROSS_STANDARD_ID):
kind = drawing_id # id와 kind가 같은 단장 도면
elif PLAN_ID.fullmatch(drawing_id):
kind = "plan"
@@ -485,6 +455,17 @@ def _read_drawing(
None,
)
if drawing_id == CROSS_STANDARD_ID:
# stored_design = B06 표준 횡단면 설정값(라우터가 실어 준다). 없으면 config 기본값.
standard = stored_design if isinstance(stored_design, dict) else None
return (
"cross_standard",
STANDARD_LABEL,
build_standard_cross_drawing(drawing_id, STANDARD_LABEL, standard),
False,
None,
)
if LIDAR_ID.fullmatch(drawing_id):
# stored_design = lidar_source()가 만든 노선 + 지표면 음영기복 그림.
if not isinstance(stored_design, dict):