feat(D 예정노선): 도엽 조각 — 공용 창고 storage/_shared/sheets · 보이는 도엽만 받기 (PLAN 606-1 · 606-2 · 요구 477)
- 새 D03_PlanAnalysis_SheetTiles.py — 도엽 도곽으로 자른 선 겹 조각(등고 · 계곡 = 전국 등고선 · 세류 · 물 면 · 도로 · 건물 · 지명 = 도엽 zip) · zip 은 프로젝트 · 공용 지형 창고에서 복사(원본 안 지움) 뒤 받기 · 빈 도엽 = 빈 조각 · 받기 실패 저장 안 함 · B04 함수 부르기만 - 라우터 길 둘 — 보이는 도엽 목록(bbox) · 조각 하나 - 새 UI_SheetTiles.ts — 보기 멈춘 뒤 보이는 도엽 · 없는 조각만 하나씩 · 12 장 이하 다 · 13~30 계곡선만 · 넘음 숨김 · 서클 - UI_Layers — 도엽 선 겹 원천을 조각으로 · 시험 606 새 · 475 옛 겹 길 단언 바꿈 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -96,9 +96,9 @@ def test_layers_turn_drops_old_answers() -> None:
|
||||
assert (
|
||||
"pending.get(slot) === job && pending.delete(slot)" in layers
|
||||
) # 옛 일이 새 기다림을 안 지움
|
||||
# 등고 · 세류 = 예정노선 겹 길(서버가 받은 범위로 자름) · 화면 상자 · 보관함 지문 걷음
|
||||
assert 'fetchPlanSheetLayer(projectId, "등고선")' in layers
|
||||
assert 'fetchPlanSheetLayer(projectId, "하천중심선")' in layers
|
||||
# 등고 · 세류 = 보이는 도엽 조각(606) · 옛 화면 상자 · 보관함 지문 걷음
|
||||
assert 'tiles.collection("등고선")' in layers
|
||||
assert 'tiles.collection("하천중심선")' in layers
|
||||
for gone in ("/geojson?layer=", "CONTOUR_PAD_M", "haveTag", "opts.have"):
|
||||
assert gone not in layers, gone
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
"""도엽 조각(PLAN 606) — 보이는 도엽 수 · 차례 · 30 장 넘음 = 목록 없음 · 조각 = 도곽 안 ·
|
||||
처음만 만듦 · 계곡선 = 등고선 중 25 m 배수 · 빈 도엽 = 빈 조각 · 받기 실패는 저장 안 함 ·
|
||||
화면 = 보이는 도엽만(12 · 30 문턱) · 옛 받은 범위 겹 길 안 씀.
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_606_sheet_tiles.py -q
|
||||
"""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from B04_PreProcess.B04_PreProcess_Engine_MapSheet import sheet5k_center, sheet5k_to_bounds
|
||||
from D03_PlanAnalysis import D03_PlanAnalysis_SheetTiles as st
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
SHEET = "36901074"
|
||||
|
||||
|
||||
def _inside(collection, rect, eps=1e-6):
|
||||
lon0, lat0, lon1, lat1 = rect
|
||||
|
||||
def walk(c):
|
||||
if isinstance(c[0], (int, float)):
|
||||
assert lon0 - eps <= c[0] <= lon1 + eps and lat0 - eps <= c[1] <= lat1 + eps
|
||||
else:
|
||||
for part in c:
|
||||
walk(part)
|
||||
|
||||
for feature in collection["features"]:
|
||||
walk(feature["geometry"]["coordinates"])
|
||||
|
||||
|
||||
def test_sheets_in_box_count_order_cap() -> None:
|
||||
lat, lon = sheet5k_center(SHEET)
|
||||
assert st.sheets_in_box((lon - 0.001, lat - 0.001, lon + 0.001, lat + 0.001)) == (1, [SHEET])
|
||||
count, sheets = st.sheets_in_box((lon - 0.02, lat - 0.02, lon + 0.02, lat + 0.02))
|
||||
assert count == len(sheets) == 9 and sheets[0] == SHEET # 가운데부터
|
||||
count, sheets = st.sheets_in_box((lon - 0.1, lat - 0.1, lon + 0.1, lat + 0.1))
|
||||
assert count > st.INDEX_MAX and sheets == []
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def shelf(tmp_path, monkeypatch):
|
||||
found = sorted(ROOT.glob(f"storage/*/*/*/B04_PreProcess/processed/map_sheets/{SHEET}.zip"))
|
||||
found += sorted((ROOT / "storage" / "_shared" / "sheets" / SHEET).glob("*.zip"))
|
||||
if not found:
|
||||
pytest.skip("도엽 zip 없음")
|
||||
monkeypatch.setattr(st, "SHEETS_ROOT", tmp_path)
|
||||
monkeypatch.setattr(st, "_project_zips", lambda no: found[:1] if no == SHEET else [])
|
||||
return tmp_path
|
||||
|
||||
|
||||
def test_zip_tile_clipped_and_made_once(shelf) -> None:
|
||||
path = st.ensure_tile(SHEET, "하천중심선")
|
||||
collection = json.loads(path.read_text(encoding="utf-8"))
|
||||
assert collection["features"]
|
||||
_inside(collection, sheet5k_to_bounds(SHEET))
|
||||
stamp = path.stat().st_mtime_ns
|
||||
assert st.ensure_tile(SHEET, "하천중심선") == path and path.stat().st_mtime_ns == stamp
|
||||
assert (shelf / SHEET / f"{SHEET}.zip").is_file() # 옮겨 담음(원본은 그대로)
|
||||
|
||||
|
||||
def test_contour_and_index(shelf) -> None:
|
||||
full = json.loads(st.ensure_tile(SHEET, st.CONTOUR).read_text(encoding="utf-8"))
|
||||
index = json.loads(st.ensure_tile(SHEET, st.INDEX).read_text(encoding="utf-8"))
|
||||
levels = [f["properties"]["등고수치"] for f in full["features"]]
|
||||
assert levels and all(isinstance(v, (int, float)) for v in levels)
|
||||
assert index["features"] and all(
|
||||
f["properties"]["등고수치"] % 25 == 0 for f in index["features"]
|
||||
)
|
||||
assert len(index["features"]) == sum(1 for v in levels if v % 25 == 0)
|
||||
_inside(full, sheet5k_to_bounds(SHEET))
|
||||
|
||||
|
||||
def test_bad_name_rejected(shelf) -> None:
|
||||
with pytest.raises(KeyError):
|
||||
st.ensure_tile(SHEET, "../x")
|
||||
with pytest.raises(KeyError):
|
||||
st.ensure_tile("1234", "건물")
|
||||
|
||||
|
||||
def _no_download(monkeypatch, reason):
|
||||
import B04_PreProcess.B04_PreProcess_Engine_SheetStore as sheet_store
|
||||
|
||||
monkeypatch.setattr(
|
||||
sheet_store,
|
||||
"ensure_sheets",
|
||||
lambda folder, nos: {"available": {}, "failed": {nos[0]: reason}},
|
||||
)
|
||||
|
||||
|
||||
def test_empty_sheet_gives_empty_tile(tmp_path, monkeypatch) -> None:
|
||||
monkeypatch.setattr(st, "SHEETS_ROOT", tmp_path)
|
||||
monkeypatch.setattr(st, "_project_zips", lambda no: [])
|
||||
_no_download(monkeypatch, "LookupError: 검색 결과 없음")
|
||||
path = st.ensure_tile("37507039", "건물")
|
||||
assert json.loads(path.read_text(encoding="utf-8"))["features"] == []
|
||||
|
||||
|
||||
def test_download_failure_not_saved(tmp_path, monkeypatch) -> None:
|
||||
monkeypatch.setattr(st, "SHEETS_ROOT", tmp_path)
|
||||
monkeypatch.setattr(st, "_project_zips", lambda no: [])
|
||||
_no_download(monkeypatch, "PermissionError: 로그인")
|
||||
with pytest.raises(RuntimeError):
|
||||
st.ensure_tile("37507039", "건물")
|
||||
assert not list(tmp_path.rglob("*.geojson"))
|
||||
|
||||
|
||||
def _src(name: str) -> str:
|
||||
return (ROOT / "D03_PlanAnalysis" / name).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_screen_uses_visible_sheets() -> None:
|
||||
tiles = _src("D03_PlanAnalysis_UI_SheetTiles.ts")
|
||||
assert "export const FULL_MAX = 12;" in tiles and "export const INDEX_MAX = 30;" in tiles
|
||||
assert '"등고선" ? "계곡선" : null' in tiles # 13~30 = 계곡선만
|
||||
layers = _src("D03_PlanAnalysis_UI_Layers.ts")
|
||||
assert "fetchPlanSheetLayer" not in layers
|
||||
assert "tiles.view(m, meta)" in layers
|
||||
assert len(layers.splitlines()) <= 700
|
||||
Reference in New Issue
Block a user