Files
Aislo/resources/tester/test_581_2_plan_soils.py
T
eomsangdonandClaude Opus 5.5 61733d064d feat(지도): 634-2 · 634-3 아이콘 표 두 장 · 묶음 메뉴 · 한 행 배선 · 호버 = 표(요구 546)
- 겹 표(map_layer_list) = 그룹1 22 줄 표 차례 · title = 호버제목 · group(수계망도 · 도로 · 토지·건물 · 제한·재해) · pages · 숨김 표 걷음 · 도로300m 한 줄(「도로」 묶음 · 기능 남김)
- 겹 줄(map_layer_bar) = 단독 넷 | 묶음 넷(여럿 고르기 메뉴 · 켠 수 배지 · 안 닫힘) | 그래픽 카드 · sync 가 단추 · 메뉴 줄 막힘 · 글을 맞춤(why = 페이지 까닭)
- 도구 표(map_toolbar) = 그룹2 17 줄 title · mapToolGroups 가 글을 표로 맞춤 · 기본 단추 생성 · 지형 칩 막힘 「수치지형도/라이다 — 까닭」
- 띠 = 한 자료 · 겹 둘(GL fillEdge 거름 · 옛 캔버스 · 범례 줄 따로) · B05 띠 받기(D03 과 같은 서버 길 · bandCollection 공용)
- D03 = 겹 줄 · 도구줄 한 행(createMapToolRow) · 222px 기댐 · 줄바꿈 CSS 걷음 · 측점 · 기울기 호버 덮어쓰기 걷음 · LAS 올리기 호버 걷음
- B05 = 세로 두 줄 → 한 행 · 호버 덮어쓰기 걷음(도구줄 · 1m 등고선 · 3D · 추천) · 겹 막힘 querySelector 덮어쓰기 → 공용 sync · 임도(업로드) 보임 + 「받은 임도 자료 없음」 막힘 · 스냅 간격 날 select → 고르기 메뉴(하나)
- 켬끔 기억 열쇠 · 측점 · 기울기 처음 값 · 그래픽 카드 취향 열쇠 둘 그대로
- 낡은 시험 고침(568_1 · 622_2 · 624_2 · 624_3 · 553_4 · 625_draw · b05_routeedit_initial · 626_3 · 390_4 · 346_2 · 353_1 · 581_2 · 584_1 · 584_3) — 표 꼴 row() · 호버 글 = 표 · 한 행 · 고르기 메뉴로 바뀐 글을 잡음 · 새 지킴 634_2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 11:40:26 +09:00

101 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""D 노선분석 GIS 겹 「다음」 묶음(PLAN 581-2) — 산림입지도 잘라 넓이 · 토양형 코드 차례
이름 없으면 글자 그대로 · 실패 = 오류(파일 안 씀) · 덮으면 다시 안 받음 · 화면 겹 정의 · 색 값.
./venv/Scripts/python.exe -m pytest resources/tester/test_581_2_plan_soils.py -q
"""
import json
import re
from pathlib import Path
import pytest
from common_util.common_util_crs import tm_to_lonlat
from D03_PlanAnalysis import D03_PlanAnalysis_Layers as layers
EPSG = 5186
BOX = (230000.0, 450000.0, 232000.0, 451000.0) # 2 × 1 km
ROOT = Path(__file__).resolve().parents[2]
def _square(x0: float, y0: float, side: float) -> dict:
ring = [(x0, y0), (x0 + side, y0), (x0 + side, y0 + side), (x0, y0 + side), (x0, y0)]
return {"type": "Polygon", "coordinates": [[list(tm_to_lonlat(x, y, EPSG)) for x, y in ring]]}
def _soil(gid: str, geometry: dict, cd: str, code: str, name: str | None) -> dict:
props = {"sltp_cd": cd, "toyanghyun": code, **({"name": name} if name else {})}
return {"id": gid, "geometry": geometry, "properties": props}
def test_clip_soils_area_order_names() -> None:
found = [
_soil("a", _square(230100.0, 450100.0, 100.0), "03", "B₃", "갈색적윤산림토양"),
_soil("b", _square(231800.0, 450800.0, 400.0), "01", "B₁", "갈색건조산림토양"), # 귀퉁이
_soil("b", _square(231800.0, 450800.0, 400.0), "01", "B₁", "갈색건조산림토양"), # 겹침
_soil("c", _square(230500.0, 450500.0, 100.0), "03", "B₃", "갈색적윤산림토양"),
_soil("d", _square(230800.0, 450100.0, 50.0), "99", "Xx", None), # 모르는 값
_soil("e", _square(240000.0, 460000.0, 100.0), "02", "B₂", "갈색약건산림토양"), # 밖
]
features, summary = layers.clip_soils(found, BOX, EPSG)
assert [row["code"] for row in summary] == ["B₁", "B₃", "Xx"]
assert summary[0]["area_m2"] == pytest.approx(200 * 200, rel=0.01)
assert summary[1] == {
"code": "B₃",
"name": "갈색적윤산림토양",
"count": 2,
"area_m2": pytest.approx(2 * 100 * 100, rel=0.01),
}
assert summary[2]["name"] == "Xx" # 이름 없으면 글자 그대로
assert len(features) == 4
assert {f["properties"]["code"] for f in features} == {"B₁", "B₃", "Xx"}
class FakeWfs:
def __init__(self, fail: bool = False) -> None:
self.fail, self.calls = fail, []
def __call__(self, typename, filename, bounds, output_dir) -> None:
self.calls.append(typename)
if self.fail:
return
feats = [_soil("a", _square(230500.0, 450200.0, 300.0), "01", "B₁", "갈색건조산림토양")]
body = {"type": "FeatureCollection", "features": feats}
(Path(output_dir) / filename).write_text(json.dumps(body), "utf-8")
def test_soils_fetch_once(tmp_path, monkeypatch) -> None:
fake = FakeWfs()
monkeypatch.setattr(layers, "request_vworld_wfs", fake)
got = layers.ensure_soils(tmp_path, BOX, EPSG)
assert got["fetched"] and fake.calls == [layers.SOIL_TYPENAME]
saved = json.loads((tmp_path / layers.SOIL_FILE).read_text("utf-8"))
assert saved["summary"][0]["count"] == 1 and len(saved["features"]) == 1
inner = (230500.0, 450100.0, 231000.0, 450900.0)
assert not layers.ensure_soils(tmp_path, inner, EPSG)["fetched"] # 덮으면 다시 안 받음
assert len(fake.calls) == 1
assert layers.ensure_soils(tmp_path, (229000.0, *BOX[1:]), EPSG)["fetched"] # 넓어지면 다시
def test_soils_fail_raises(tmp_path, monkeypatch) -> None:
monkeypatch.setattr(layers, "request_vworld_wfs", FakeWfs(fail=True))
with pytest.raises(RuntimeError):
layers.ensure_soils(tmp_path, BOX, EPSG)
assert not (tmp_path / layers.SOIL_FILE).exists()
def test_screen_def_and_colors() -> None:
defs = (ROOT / "A00_Common" / "map" / "map_layer_list.ts").read_text("utf-8") # 624-2
# 634-2 표 한 줄 = row(열쇠, 아이콘, 호버제목, 묶음[, true]) · true 없음 = 처음 끔
entry = re.search(r'row\("soils", "(\w+)", "[^"]+", (?:"\w+"|null)(, true)?\)', defs)
assert entry and not entry.group(2) # 처음 값 끔
icons = (ROOT / "ui_template" / "ui_template_icons.ts").read_text("utf-8")
assert re.search(rf"^\s+{entry.group(1)}:", icons, re.M)
theme = (ROOT / "ui_template" / "ui_template_theme.css").read_text("utf-8")
assert all(f"--draw-map-soil-{n}:" in theme for n in range(1, 7))
page = (ROOT / "D03_PlanAnalysis" / "D03_PlanAnalysis_UI_LayerPaint.ts").read_text(
"utf-8"
) # 586-2
assert "if (!on.soils || !data.soils) return;" in page
assert page.count("base: true,") == page.count("draw: (context, map) =>") # 겹 모두 바탕(582)