fix(B07): 횡단면도 박스가 화면 덧그림(B06 설계선·구조물)까지 1 mm 로 감쌈
- 덧그림 범위를 서버가 화면과 같은 TS 로 셈 — Node 진입점 B07_DesignDetail_Cross_Extent_Node(최소 DOM 위에서 오프스크린 SVG 그리기 그대로) · 번들 build:b07-extent - 화면 그리기·수확 부분을 B07_DesignDetail_Cross_Overlay 로 떼어 화면과 Node 가 한 벌로 씀 - 장 배치·블록 테두리가 측점별 덧그림 범위를 덮음(목록·장 열기·확정·수정 네 길 모두 같은 계획) - 글자는 CAD 그리기대로 세로 가운데 · 폭은 글꼴 어림(한글 1.0 · 나머지 0.6 배) - 번들 낡음 판정에 B07 맨 위 TS 포함 - 검증_sub4: 66개 박스 ↔ 그림(덧그림·글자 실폭 포함) 모두 1.0 mm · 잘림 0 · 겹침 0 · 20장 → 21장 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP
This commit is contained in:
@@ -111,6 +111,7 @@ def _drawing_list(
|
||||
project_root: Path,
|
||||
longitudinal_path: Path,
|
||||
designs: dict[int | float, dict[str, Any]] | None = None,
|
||||
overlays: dict[int | float, tuple[float, float, float, float]] | None = None,
|
||||
) -> list[DesignDrawingItem]:
|
||||
longitudinal = _read_json(longitudinal_path)
|
||||
station_by_chainage = _station_map(longitudinal)
|
||||
@@ -128,7 +129,7 @@ def _drawing_list(
|
||||
# 횡단 장 계획이 실패해도 나머지 도면은 목록에 남긴다 — 예전에는 `cross_sections/`
|
||||
# 하나가 없으면 표지·종단면도·토적도·유역도까지 함께 사라졌다(2026-09-01 지적).
|
||||
try:
|
||||
sheets = _cross_sheet_plan(project_root, longitudinal_path, designs)
|
||||
sheets = _cross_sheet_plan(project_root, longitudinal_path, designs, overlays)
|
||||
except (FileNotFoundError, ValueError, OSError) as exc:
|
||||
logger.warning("B07 횡단 장 계획 실패 — 나머지 도면만 싣는다: %s", exc)
|
||||
sheets = []
|
||||
@@ -214,6 +215,7 @@ def _cross_sheet_plan(
|
||||
project_root: Path,
|
||||
longitudinal_path: Path,
|
||||
designs: dict[int | float, dict[str, Any]] | None = None,
|
||||
overlays: dict[int | float, tuple[float, float, float, float]] | None = None,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""측점 도면을 A1 장으로 나눈 계획 — 목록과 도면 생성이 같은 결과를 쓴다.
|
||||
|
||||
@@ -231,7 +233,8 @@ def _cross_sheet_plan(
|
||||
chainage = cross_station(source.get("chainage_m") or parse_cross_key(match.group(1)))
|
||||
design = (designs or {}).get(chainage)
|
||||
design_line = _cross_design_line(longitudinal_path, source, design)
|
||||
width, height = section_block_size(source, design_line, design=design)
|
||||
overlay = (overlays or {}).get(chainage) # 화면 덧그림 범위(68-3)
|
||||
width, height = section_block_size(source, design_line, design=design, overlay=overlay)
|
||||
blocks.append((chainage, width, height))
|
||||
return plan_cross_sheets(blocks)
|
||||
|
||||
@@ -342,6 +345,7 @@ def _cross_section_input(
|
||||
longitudinal: dict[str, Any],
|
||||
chainage: int | float,
|
||||
design: dict[str, Any] | None,
|
||||
overlay: tuple[float, float, float, float] | None = None,
|
||||
) -> dict[str, Any] | None:
|
||||
"""한 측점의 장 배치 입력(원본·계획선·수량표·제목)을 만든다."""
|
||||
path = find_cross_file(longitudinal_path.parent.parent / "cross_sections", chainage)
|
||||
@@ -356,6 +360,7 @@ def _cross_section_input(
|
||||
"design_line": _cross_design_line(longitudinal_path, source, design),
|
||||
"quantity_table": _quantity_table(source, design),
|
||||
"title": station_no_label(float(source.get("chainage_m", chainage)), interval),
|
||||
"overlay": overlay,
|
||||
}
|
||||
|
||||
|
||||
@@ -364,10 +369,12 @@ def _read_cross_sheet(
|
||||
longitudinal_path: Path,
|
||||
drawing_id: str,
|
||||
stored_designs: dict[str, Any] | None,
|
||||
overlays: dict[int | float, tuple[float, float, float, float]] | None = None,
|
||||
) -> tuple[str, str, dict[str, Any], bool, dict[str, float | None] | None]:
|
||||
"""횡단 장 하나를 만든다. stored_designs는 {측점: 설계 지정} 묶음이다."""
|
||||
"""횡단 장 하나를 만든다. stored_designs는 {측점: 설계 지정}, overlays는 {측점: 덧그림 범위}."""
|
||||
designs = stored_designs if isinstance(stored_designs, dict) else {}
|
||||
plan = _cross_sheet_plan(project_root, longitudinal_path, designs)
|
||||
overlays = overlays or {}
|
||||
plan = _cross_sheet_plan(project_root, longitudinal_path, designs, overlays)
|
||||
sheet = next((item for item in plan if item["id"] == drawing_id), None)
|
||||
if sheet is None:
|
||||
raise FileNotFoundError("요청한 횡단 장을 찾을 수 없습니다.")
|
||||
@@ -375,7 +382,13 @@ def _read_cross_sheet(
|
||||
sections = [
|
||||
section
|
||||
for section in (
|
||||
_cross_section_input(longitudinal_path, longitudinal, chainage, designs.get(chainage))
|
||||
_cross_section_input(
|
||||
longitudinal_path,
|
||||
longitudinal,
|
||||
chainage,
|
||||
designs.get(chainage),
|
||||
overlays.get(chainage),
|
||||
)
|
||||
for chainage in sheet["chainages"]
|
||||
)
|
||||
if section is not None
|
||||
@@ -389,6 +402,7 @@ def _read_drawing(
|
||||
longitudinal_path: Path,
|
||||
drawing_id: str,
|
||||
stored_design: dict[str, Any] | None = None,
|
||||
overlays: dict[int | float, tuple[float, float, float, float]] | None = None,
|
||||
) -> tuple[str, str, dict[str, Any], bool, dict[str, float | None] | None]:
|
||||
"""(kind, label, drawing, confirmed, quantity_table)를 반환한다.
|
||||
|
||||
@@ -522,7 +536,9 @@ def _read_drawing(
|
||||
)
|
||||
|
||||
if CROSS_SHEET_ID.fullmatch(drawing_id):
|
||||
return _read_cross_sheet(project_root, longitudinal_path, drawing_id, stored_design)
|
||||
return _read_cross_sheet(
|
||||
project_root, longitudinal_path, drawing_id, stored_design, overlays
|
||||
)
|
||||
|
||||
cross_match = _CROSS_ID.fullmatch(drawing_id)
|
||||
if not cross_match:
|
||||
|
||||
Reference in New Issue
Block a user