Merge remote-tracking branch 'origin/sub_laptop_6' into main_laptop_1

# Conflicts:
#	B07_DesignDetail/B07_DesignDetail_Engine_Cad_PlanKinds.py
#	B07_DesignDetail/B07_DesignDetail_Router_Support_Plan.py
#	resources/tester/test_b07_plan_kinds.py
This commit is contained in:
2026-10-08 13:56:56 +09:00
13 changed files with 541 additions and 641 deletions
@@ -54,6 +54,10 @@ from B07_DesignDetail.B07_DesignDetail_Router_Support_Io import (
_read_manifest,
_write_manifest,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support_Landuse import (
LANDUSE_PIECES,
landuse_pieces,
)
from common_util.common_util_json import atomic_write_json
from common_util.common_util_route_profile import design_elevation_from_longitudinal
from config.config_system import DRAWING_SCALE_PLAN
@@ -66,7 +70,7 @@ _REFUGE_OFFSET_M = 8.0 # 대피소 · 사토장 라벨을 중심선에서 띄
def plan_title(name: str) -> str:
return f"계획평면도({name})"
return f"평면도({name})"
# ── 종류 ─────────────────────────────────────────────
@@ -76,11 +80,38 @@ def _kinds_dir(project_root: Path) -> Path:
return _design_root(project_root) / "plan_kinds"
# 이관 표시 — 있으면 용지도 종류를 이미 더해 준 폴더(지운 뒤 되살리지 않음).
_LANDUSE_MARK = "_landuse_added"
def _add_landuse_once(folder: Path) -> None:
"""93장 앞에 종류 파일을 내린 프로젝트 — 기본 종류 「용지도」를 한 번 더한다."""
mark = folder / _LANDUSE_MARK
if mark.exists():
return
landuse = next(kind for kind in DEFAULT_KINDS if kind["id"] == "landuse")
documents = []
for path in folder.glob("*.json"):
try:
documents.append(_read_json(path))
except (OSError, ValueError):
continue
names = {str(document.get("name")) for document in documents}
if not (folder / "landuse.json").exists() and landuse["name"] not in names:
order = max((int(document.get("order") or 0) for document in documents), default=-1) + 1
atomic_write_json(
folder / "landuse.json",
{"name": landuse["name"], "pieces": list(landuse["pieces"]), "order": order},
)
mark.touch()
def list_kinds(project_root: Path) -> list[dict[str, Any]]:
"""종류 목록 [{id, name, pieces}] — 차례대로. 파일이 없으면 기본 넷."""
"""종류 목록 [{id, name, pieces}] — 차례대로. 파일이 없으면 기본 종류."""
folder = _kinds_dir(project_root)
if not folder.is_dir():
return [{**kind, "pieces": list(kind["pieces"])} for kind in DEFAULT_KINDS]
_add_landuse_once(folder)
rows: list[tuple[int, str, dict[str, Any]]] = []
for path in folder.glob("*.json"):
if not KIND_ID.fullmatch(path.stem):
@@ -113,6 +144,7 @@ def _materialize(project_root: Path) -> list[dict[str, Any]]:
folder / f"{kind['id']}.json",
{"name": kind["name"], "pieces": kind["pieces"], "order": order},
)
(folder / _LANDUSE_MARK).touch()
return kinds
@@ -412,6 +444,11 @@ def build_pieces(
pieces["lidar"] = {"image": image, "box": list(image_box)}
except (FileNotFoundError, ValueError, OSError):
pieces["lidar"] = {"image": None, "box": None}
if set(LANDUSE_PIECES) & set(wanted):
# 라벨은 이 장 구간이 아니라 노선 전체를 비켜 간다 — 도곽 안에 다른 구간이 들 수 있다.
pieces.update(
landuse_pieces(project_root, context.crs, box, [(x, y) for _c, x, y in route])
)
if "ip_table" in wanted:
pieces["ip_table"] = ip_table_piece(
pieces, _load_design_curves(project_root), route, box, chunk, total