feat(B07): 종단도 장마다 우측 상단 평면 위치도 · 종단 ⚙ 「평면도」 척도 칸 (521-2 · 요구 340-2)

- 새 Engine_Cad_LongPlan — 작도 영역 우상단 5 mm 안쪽 150×100 mm 칸 · 자동 = 전체 노선 맞춤(분모 500 올림) · 척도 정함 = 이 장 중심 확대 · 밖 노선 흐린 파선 · 칸 밖 잘림 · 이 장 굵게 · 시 · 종점 측점 · 방위표 · 「평면도 S=1/n」 · 「n/N 장」 · 좌표 없으면 안 그림
- 장 나눔 — 그래프가 칸을 덮으면 측점 줄여 장 더 나눔 · 장 목록에 number · total
- 축척 — longitudinal.plan 기본 자동 · 범위 1/500~1/50,000 · ⚙ 칸 = 서버 기본값 열쇠 그대로(셋째 칸 + 자동)
- 칸 앞 확정 종단 저장본 — 목록 받을 때 종단만 한 번 모두 풂(DRAWING_FORMAT 그대로)
- 시험 — 칸 자리 · 안 겹침 · 장마다 강조 · 척도 확대 · 좌표 없음 · 한 번 풂 · plan 범위 · ⚙ 평면 칸

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 08:01:02 +09:00
co-authored by Claude Opus 5.5
parent b522a52622
commit df0e64ffe2
12 changed files with 472 additions and 37 deletions
@@ -42,6 +42,11 @@ from B07_DesignDetail.B07_DesignDetail_Engine_Cad import (
polyline_entity,
station_no_label,
)
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_LongPlan import (
LONG_PLAN_LAYER_ID,
long_plan_entities,
plan_box_overlaps,
)
from B07_DesignDetail.B07_DesignDetail_Engine_Template import (
drawing_scale,
entities_bbox,
@@ -93,12 +98,14 @@ def _span(stations: list[dict[str, Any]], index: int, take: int) -> dict[str, fl
def _fits_sheet(longitudinal: dict[str, Any], span: dict[str, float]) -> bool:
"""이 구간을 고정 축척으로 그렸을 때 A1 작도 영역에 드는가."""
bbox = entities_bbox(_long_content(longitudinal, "probe", span))
"""이 구간을 고정 축척으로 그렸을 때 A1 작도 영역에 들고 평면 위치도 칸을 안 덮는가."""
content = _long_content(longitudinal, "probe", span)
bbox = entities_bbox(content)
if bbox is None:
return True
usable_w, usable_h = usable_area()
return bbox[2] - bbox[0] <= usable_w + 1e-6 and bbox[3] - bbox[1] <= usable_h + 1e-6
fits = bbox[2] - bbox[0] <= usable_w + 1e-6 and bbox[3] - bbox[1] <= usable_h + 1e-6
return fits and not plan_box_overlaps(longitudinal, content, bbox)
def longitudinal_chunks(longitudinal: dict[str, Any]) -> list[dict[str, Any]]:
@@ -124,9 +131,10 @@ def longitudinal_chunks(longitudinal: dict[str, Any]) -> list[dict[str, Any]]:
break
index += take - 1 # 경계 1측점 중복
if len(spans) == 1:
return [{"id": "longitudinal", "label": "종단도", **spans[0]}]
return [{"id": "longitudinal", "label": "종단도", "number": 1, "total": 1, **spans[0]}]
return [
{"id": f"longitudinal_{number}", "label": f"종단도({number})", **span}
{"id": f"longitudinal_{number}", "label": f"종단도({number})", "number": number, **span}
| {"total": len(spans)}
for number, span in enumerate(spans, start=1)
]
@@ -660,6 +668,7 @@ def build_longitudinal_drawing(
# A1 도각: 콘텐츠가 이미 종이 mm라 도각도 실치수(1:1)로 두고 위치만 맞춘다.
# 그림 좌하단 = 작도영역 좌하단 — 장마다 같은 자리에서 시작한다.
bbox = entities_bbox(entities)
entities.extend(long_plan_entities(longitudinal, drawing_id, chunk, bbox)) # 521-2
if bbox:
entities.extend(
frame_entities(
@@ -682,6 +691,7 @@ def build_longitudinal_drawing(
_layer(DESIGN_LAYER_ID, "계획선"),
_layer(LONG_GRID_LAYER_ID, "그래프 격자", locked=True),
_layer(LONG_TABLE_LAYER_ID, "측점표"),
_layer(LONG_PLAN_LAYER_ID, "평면 위치도"),
_layer(FRAME_LAYER_ID, "도각", locked=True),
],
}