feat(b07): 평면도 종류마다 축척 고르기 — 1/600 · 1/1,000 · 1/1,200 기본 · 유역도 1/6,000 고정(119-1)

- 종류 파일 scale(없거나 목록 밖이면 1200) · 추가 · 업데이트 인자 · 목록 밖 거절
- 장 나눔 · 도곽 범위 · 배경 절취 · 축척 글 · 도곽 칸 · IP 표 · 필지 라벨 · 측점 눈금 실거리 환산이 축척 따라감(함수 인자)
- 「종류」 폼에 공용 「축척」 고르기 · 유역도 양식은 잠금 표시
- 시험 test_119_b07_plan_scale 새로 · test_b07_plan_kinds 종류 dict 에 scale

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
This commit is contained in:
2026-10-08 18:29:18 +09:00
co-authored by Claude Opus 5.5
parent 5f64633df3
commit 1827cd8bb5
13 changed files with 352 additions and 62 deletions
@@ -6,7 +6,7 @@
있고, 종류는 그중 무엇을 얹을지 고른 목록이다. 이 모듈은 조각 기하 계산과 도면 조립만
한다(파일 입출력 없음).
좌표 규약: 종이 mm = (사업지 좌표 m - 그 장 도곽 최소점) x MM (1/1,200).
좌표 규약: 종이 mm = (사업지 좌표 m - 그 장 도곽 최소점) x (1000 / 종류 축척 분모) (기본 1/1,200).
"""
import math
@@ -372,7 +372,7 @@ def _reading(nx: float, ny: float) -> tuple[float, float]:
def _piece_entities(
drawing_id: str, piece: str, data: dict[str, Any], paper: Any
drawing_id: str, piece: str, data: dict[str, Any], paper: Any, mm: float = MM
) -> list[dict[str, Any]]:
layer, color = layer_id(piece), _COLORS.get(piece, TABLE_LABEL_COLOR)
out: list[dict[str, Any]] = []
@@ -446,8 +446,8 @@ def _piece_entities(
nx, ny = item["nx"], item["ny"]
line(
[
(item["x"] - nx * _TICK_MM / MM, item["y"] - ny * _TICK_MM / MM),
(item["x"] + nx * _TICK_MM / MM, item["y"] + ny * _TICK_MM / MM),
(item["x"] - nx * _TICK_MM / mm, item["y"] - ny * _TICK_MM / mm),
(item["x"] + nx * _TICK_MM / mm, item["y"] + ny * _TICK_MM / mm),
],
f":{index}",
)
@@ -468,7 +468,7 @@ def _piece_entities(
elif piece == "endpoints":
for index, item in enumerate(data.get("items") or []):
nx, ny = item["nx"], item["ny"]
reach = 6.0 / MM # 종이 6mm 막대
reach = 6.0 / mm # 종이 6mm 막대
line(
[
(item["x"] - nx * reach, item["y"] - ny * reach),
@@ -482,7 +482,7 @@ def _piece_entities(
elif piece == "refuge":
size = 2.0 # 네모 기호 반크기(종이 mm)
for index, item in enumerate(data.get("items") or []):
x, y, half = item["x"], item["y"], size / MM
x, y, half = item["x"], item["y"], size / mm
corners = [(-1, -1), (1, -1), (1, 1), (-1, 1), (-1, -1)]
line([(x + sx * half, y + sy * half) for sx, sy in corners], f":{index}")
cx, cy = paper((x, y))
@@ -531,19 +531,21 @@ def build_plan_kind_drawing(
label: str,
box: tuple[float, float, float, float],
pieces: dict[str, dict[str, Any]],
scale: int = DRAWING_SCALE_PLAN,
) -> dict[str, Any]:
"""고른 조각만 얹어 계획평면도 한 장을 만든다. `box` = 그 장 도곽 범위(실좌표 m)."""
min_x, min_y = box[0], box[1]
mm = 1000.0 / scale
def paper(point: Any) -> tuple[float, float]:
return ((point[0] - min_x) * MM, (point[1] - min_y) * MM)
return ((point[0] - min_x) * mm, (point[1] - min_y) * mm)
entities: list[dict[str, Any]] = []
for piece in PIECE_IDS:
if piece in pieces:
entities.extend(_piece_entities(drawing_id, piece, pieces[piece], paper))
entities.extend(_piece_entities(drawing_id, piece, pieces[piece], paper, mm))
# 도곽 · 방위표 자리는 조각과 무관하게 같은 자리 — 그 장 범위를 기준으로 잡는다.
frame_box = (0.0, 0.0, (box[2] - min_x) * MM, (box[3] - min_y) * MM)
frame_box = (0.0, 0.0, (box[2] - min_x) * mm, (box[3] - min_y) * mm)
entities.extend(
compass_entities(
drawing_id,
@@ -570,7 +572,7 @@ def build_plan_kind_drawing(
entities.append(
_text_entity(
f"{drawing_id}:scale",
f"S = 1/{DRAWING_SCALE_PLAN:,}",
f"S = 1/{scale:,}",
max_bx,
max_by + 5.0,
"b07-plan-title",
@@ -584,7 +586,7 @@ def build_plan_kind_drawing(
drawing_id,
entities_bbox(entities) or bbox,
fit=False,
fields={"도면명": label, **scale_fields(("", DRAWING_SCALE_PLAN))},
fields={"도면명": label, **scale_fields(("", scale))},
)
)
layers = [