fix(B07): 용지도 구역이 한 필지 안이면 어느 필지인지 표기

- 필지 경계가 하나도 안 보이고 도곽을 통째로 감싼 필지가 있으면 정보 묶음 맨 위에 「구역 전체가 이 필지 안 (시군구 읍면동 리)」 한 줄
- 검증_sub4(용화리 국유림 산77-15임 한 필지 안): 화면에 안내 1개 + 지번·지목·면적·소유자

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP
This commit is contained in:
2026-10-06 23:14:44 +09:00
co-authored by Claude Opus 5.5
parent 67bba96227
commit 006ed27d79
2 changed files with 58 additions and 0 deletions
@@ -109,6 +109,16 @@ def _parcel_info_lines(props: dict[str, Any]) -> list[str]:
]
def _enclosing_note(props: dict[str, Any]) -> str:
"""구역 전체가 한 필지 안일 때 정보 묶음 맨 위 줄 — 소재지(시군구 읍면동 리)를 붙인다."""
place = " ".join(
str(props[key]).strip()
for key in ("sgg_nm", "emd_nm", "ri_nm")
if isinstance(props.get(key), str) and props[key].strip()
)
return f"구역 전체가 이 필지 안 ({place})" if place else "구역 전체가 이 필지 안"
def _legend_entities(drawing_id: str, origin: tuple[float, float]) -> list[dict[str, Any]]:
"""범례 — 유역도에서 유역 정보표가 있던 자리(오른쪽 칸)에 놓는다."""
entities: list[dict[str, Any]] = []
@@ -217,6 +227,7 @@ def build_landuse_drawing(
# 필지 경계 + 필지 정보. 도곽에 잘려 조각이 여럿인 필지도 정보는 한 번만 —
# 가장 큰 조각 가운데에 적는다(구역 안 필지 수 = 정보 묶음 수).
spots: dict[str, tuple[float, tuple[float, float], dict[str, Any]]] = {}
enclosing: set[str] = set() # 도곽을 통째로 감싼 필지
for index, parcel in enumerate(parcels):
ring = parcel.get("ring") or []
props = parcel.get("props") or {}
@@ -234,14 +245,19 @@ def build_landuse_drawing(
elif label_at is not None:
# 도곽을 통째로 감싼 필지 — 경계선이 없으니 지정된 자리에 정보만 적는다.
size, center = 0.0, paper(tuple(label_at))
enclosing.add(str(props.get("pnu") or f"#{index}"))
else:
continue
key = str(props.get("pnu") or f"#{index}")
if key not in spots or size > spots[key][0]:
spots[key] = (size, center, props)
# 필지 경계가 하나도 안 보이면(구역이 한 필지 안) 어느 필지인지 글로 밝힌다(68-2).
no_outline = not any(len(parcel.get("ring") or []) >= 2 for parcel in parcels)
jibun: list[dict[str, Any]] = []
for key, (_size, center, props) in spots.items():
lines = _parcel_info_lines(props)
if no_outline and key in enclosing:
lines = [_enclosing_note(props), *lines]
top = center[1] + (len(lines) - 1) / 2.0 * _INFO_LINE_GAP
for row, text in enumerate(lines):
if text: