- 도곽 겹 N3A_H0010000(면) 도 읽음 — 섬 · 해안 작은 zip 은 선 도곽 · 도로 면 없이 면 도곽뿐 - Ver2.0 이 NGI · NDA 뿐인 도엽 = LookupError(zip 없음) — 옛 길은 NGI 글을 zip 으로 받다 로그인 실패로 오판 - 공용 지형 받기: ValueError(도곽이 번호 자리와 어긋남 = 제주 · 울릉 번호 체계) 도 빈 지형 · 로그인 · 망 실패는 그대로 실패 - 시험 test_628_3_sheet_fetch_fallback 새로 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
82 lines
3.3 KiB
Python
82 lines
3.3 KiB
Python
"""628-3 — 전국 0차곡 이웃 도엽 받기 실패 셋: 면 도곽(N3A_H0010000) · zip 없는 도엽(NGI 뿐) ·
|
|
도곽이 번호 자리와 어긋난 zip(제주 · 울릉) = 빈 지형 · 로그인 · 망 실패는 그대로 실패."""
|
|
|
|
import sys
|
|
import tempfile
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
import geopandas as gpd
|
|
import pytest
|
|
from shapely.geometry import box
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
|
|
|
|
from B04_PreProcess import B04_PreProcess_Engine_SheetStore as sheet_store # noqa: E402
|
|
from B04_PreProcess.B04_PreProcess_Engine_MapSheet import sheet5k_to_bounds # noqa: E402
|
|
from common_util import common_util_terrain_store as store # noqa: E402
|
|
|
|
SHEET = "34616006"
|
|
CRS = "EPSG:5186"
|
|
|
|
|
|
def _make_zip(path: Path, code: str, bb: tuple[float, float, float, float]) -> None:
|
|
with tempfile.TemporaryDirectory() as td, zipfile.ZipFile(path, "w") as zf:
|
|
gdf = gpd.GeoDataFrame(geometry=[box(*bb)], crs="EPSG:4326").to_crs(CRS)
|
|
gdf.to_file(Path(td) / f"{code}.shp")
|
|
for f in Path(td).glob(f"{code}.*"):
|
|
zf.write(f, f.name)
|
|
|
|
|
|
def test_면_도곽만_있는_섬_도엽_받기_통과(tmp_path):
|
|
z = tmp_path / f"{SHEET}.zip"
|
|
_make_zip(z, "N3A_H0010000", sheet5k_to_bounds(SHEET))
|
|
entry = sheet_store.ingest_zip(tmp_path / "store", z, sheet_no=SHEET)
|
|
for got, want in zip(entry["bounds_wgs84"], sheet5k_to_bounds(SHEET)):
|
|
assert got == pytest.approx(want, abs=1e-6)
|
|
|
|
|
|
def test_도곽이_번호_자리와_어긋나면_ValueError(tmp_path):
|
|
w, s, e, n = sheet5k_to_bounds(SHEET)
|
|
z = tmp_path / f"{SHEET}.zip"
|
|
_make_zip(z, "N3A_H0010000", (w, s - 0.1, e, n - 0.1)) # 제주식 0.1° 어긋남
|
|
with pytest.raises(ValueError, match="정합하지 않음"):
|
|
sheet_store.ingest_zip(tmp_path / "store", z, sheet_no=SHEET)
|
|
|
|
|
|
def test_zip_없는_도엽은_LookupError_받기_안_함(tmp_path, monkeypatch):
|
|
rows = [
|
|
{"ds_sq": 1, "file_no": 1, "file_nm": f"{SHEET}.nda", "file_extsn": "nda"},
|
|
{"ds_sq": 1, "file_no": 2, "file_nm": f"{SHEET}.ngi", "file_extsn": "ngi"},
|
|
]
|
|
monkeypatch.setattr(sheet_store, "search_sheet_files", lambda no, version=2: rows)
|
|
|
|
def no_fetch(*_a, **_k):
|
|
raise AssertionError("받기 안 함")
|
|
|
|
monkeypatch.setattr(sheet_store, "_fetch_sheet_payload", no_fetch)
|
|
monkeypatch.setattr(sheet_store, "vworld_login", no_fetch)
|
|
with pytest.raises(LookupError, match="zip 없음"):
|
|
sheet_store.download_sheet(tmp_path, SHEET)
|
|
result = sheet_store.ensure_sheets(tmp_path, [SHEET])
|
|
assert result["failed"][SHEET].startswith("LookupError")
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("reason", "empty"),
|
|
[
|
|
("LookupError: 검색 결과 없음", True),
|
|
("LookupError: Ver2.0 zip 없음(nda, ngi)", True),
|
|
("ValueError: _dl_x.zip: 어떤 좌표계 후보로도 도엽번호 도곽과 정합하지 않음", True),
|
|
("PermissionError: 재로그인 후에도 실패", False),
|
|
("URLError: timed out", False),
|
|
],
|
|
)
|
|
def test_가운데_도엽_받기_실패_가름(monkeypatch, reason, empty):
|
|
monkeypatch.setattr(
|
|
sheet_store, "ensure_sheets", lambda d, nos: {"available": {}, "failed": {nos[0]: reason}}
|
|
)
|
|
zips, failure = store._fetch_zips(SHEET, lambda p, s: None)
|
|
assert zips == {}
|
|
assert failure == (None if empty else reason)
|