# -*- coding: utf-8 -*- """141-4 평면도 여러 장 — 노선 따라 자르기 유지 + 맞춤선 · 이웃 구간 흐리게 · 「n/N장」 · 돌린 맞춤 뺌.""" from __future__ import annotations import math from pathlib import Path from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Plan import ( _chunk_span_m, plan_chunks, sheet_links, ) from B07_DesignDetail.B07_DesignDetail_Engine_Cad_PlanKinds import ( SHEET_LAYER, build_plan_kind_drawing, ) from B07_DesignDetail.B07_DesignDetail_Router_Support_Plan import plan_kind_items # 남북으로 곧은 노선 1,200 m · 측점 20 m STATIONS = [(float(c), 0.0, float(c)) for c in range(0, 1201, 20)] def test_돌린_맞춤_빼기_남북_노선은_그림칸_높이로_나눔(): span_w, span_h = _chunk_span_m(1200) assert span_h < 800 < span_w # 옛 규칙 = 돌려 보면 한 장(그림칸 높이를 넘침) chunks = plan_chunks(STATIONS[:41], 1200) # 800 m assert len(chunks) == 2 for chunk in chunks: assert chunk["end_m"] - chunk["start_m"] <= span_h def test_맞춤선_경계_측점_직각_이웃_장_번호(): chunks = plan_chunks(STATIONS, 1200) total = len(chunks) assert total == 3 middle = chunks[1] box = (-300.0, middle["start_m"] - 10.0, 300.0, middle["end_m"] + 10.0) mm = 1000.0 / 1200 links = sheet_links(STATIONS, middle, total, box, 20.0, mm, neighbors=True) first, last = links["lines"] start_no, end_no = int(middle["start_m"] // 20), int(middle["end_m"] // 20) assert first["label"] == f"MATCH LINE NO.{start_no} · 1장 이어짐" assert last["label"] == f"MATCH LINE NO.{end_no} · 3장 이어짐" (ax, ay), (bx, by) = first["points"] assert ay == by == middle["start_m"] # 남북 노선에 직각 = 동서 assert math.hypot(bx - ax, by - ay) * mm == 60.0 # 종이 60 mm # 이웃 구간 노선 = 도곽 안만(앞 · 뒤 10 m) assert len(links["neighbors"]) == 2 for line in links["neighbors"]: assert all(box[1] <= y <= box[3] for _x, y in line) # 첫 장 · 끝 장은 한쪽만 · 중심선 안 고르면 이웃 노선 없음 only = sheet_links(STATIONS, chunks[0], total, box, 20.0, mm, neighbors=False) assert [item["label"].endswith("· 2장 이어짐") for item in only["lines"]] == [True] assert only["neighbors"] == [] def test_도면에_맞춤선_층_글은_다른_글과_안_겹침(): chunks = plan_chunks(STATIONS, 1200) middle = chunks[1] box = (-300.0, middle["start_m"] - 10.0, 300.0, middle["end_m"] + 10.0) mm = 1000.0 / 1200 links = sheet_links(STATIONS, middle, 3, box, 20.0, mm, neighbors=True) at = middle["start_m"] pieces = { "sheet_links": links, # 맞춤선 글 자리에 시종점 글 후보가 처음 놓이는 견본 "endpoints": {"items": [{"label": "시점 No.0", "x": 0.0, "y": at, "nx": 1.0, "ny": 0.0}]}, } drawing = build_plan_kind_drawing("plan_x_2", "평면도(x) 2/3장", box, pieces, 1200) sheet = [e for e in drawing["entities"] if e["layerId"] == SHEET_LAYER] labels = sorted(e["shapeData"]["label"] for e in sheet if e["type"] == "Text") assert labels == [line["label"] for line in links["lines"]] assert any(layer["id"] == SHEET_LAYER for layer in drawing["layers"]) assert sum(e["type"] == "PolyLine" for e in sheet) == 4 # 맞춤선 둘 + 이웃 노선 둘 def test_목록_도면명_n_N장(tmp_path: Path): stations = [{"chainage_m": c, "center_x": x, "center_y": y} for c, x, y in STATIONS] items = [ i for i in plan_kind_items(tmp_path, {"stations": stations}) if i["plan_kind"] == "terrain" ] assert [item["label"] for item in items] == [f"평면도(지형) {n}/3장" for n in (1, 2, 3)]