- 도엽 파서 — zip 안 .cpg 가 없으면 encoding cp949 (latin-1 로 읽어 「등고수치」 칸 이름이 깨지던 흠)
- 병합 열쇠 {"sheets", "parser"} — B04 · D03 둘 다 · 옛 깨진 병합본은 다음 받기 때 다시 지음
- 새 지킴 시험 test_561_1 — .cpg 없는 cp949 견본 → 등고수치 읽힘
- 재현(4250c7bc tmp 사본) — 2026 구간 지형면 0 셀 → 201,088 셀 · 등고수치 빈 선 5,280 → 0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
"""PLAN 561-1 — `.cpg` 없는 도엽 dbf = cp949 로 읽음 · 병합 열쇠에 파서 판 번호.
|
|
|
|
./venv/Scripts/python.exe -m pytest resources/tester/test_561_1_sheet_encoding.py -q
|
|
|
|
`.cpg` 없는 dbf 를 그냥 읽으면 latin-1 → 칸 이름 「등고수치」가 깨져 등고 높이가 빔
|
|
(D 프로젝트 4250c7bc 「등고 라인 94단을 격자에 굽어 0셀」).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import zipfile
|
|
from pathlib import Path
|
|
|
|
import geopandas as gpd
|
|
from shapely.geometry import LineString
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
import B04_PreProcess.B04_PreProcess_Engine_SheetParser as parser # noqa: E402
|
|
|
|
BASE = "N3L_F0010000"
|
|
|
|
|
|
def _sheet_zip(tmp_path: Path, with_cpg: bool) -> Path:
|
|
"""등고선 두 줄짜리 도엽 zip — dbf 는 cp949 · `.cpg` 는 고름."""
|
|
shp_dir = tmp_path / ("cpg" if with_cpg else "nocpg")
|
|
shp_dir.mkdir()
|
|
gdf = gpd.GeoDataFrame(
|
|
{"등고수치": [100.0, 105.0], "구분": ["주곡선", "주곡선"]},
|
|
geometry=[LineString([(0, 0), (10, 0)]), LineString([(0, 5), (10, 5)])],
|
|
crs="EPSG:5186",
|
|
)
|
|
gdf.to_file(shp_dir / f"{BASE}.shp", encoding="cp949")
|
|
cpg = shp_dir / f"{BASE}.cpg"
|
|
if with_cpg:
|
|
cpg.write_text("CP949", encoding="ascii")
|
|
else:
|
|
cpg.unlink(missing_ok=True)
|
|
zip_path = tmp_path / f"{shp_dir.name}.zip"
|
|
with zipfile.ZipFile(zip_path, "w") as zf:
|
|
for f in shp_dir.iterdir():
|
|
zf.write(f, f.name)
|
|
return zip_path
|
|
|
|
|
|
def _read(zip_path: Path) -> gpd.GeoDataFrame:
|
|
gdf = parser._read_layer_from_zip(zip_path, "N3L", "F0010000", "EPSG:5186")
|
|
assert gdf is not None
|
|
return gdf
|
|
|
|
|
|
def test_no_cpg_reads_cp949(tmp_path):
|
|
gdf = _read(_sheet_zip(tmp_path, with_cpg=False))
|
|
assert "등고수치" in gdf.columns
|
|
assert sorted(gdf["등고수치"].tolist()) == [100.0, 105.0]
|
|
assert set(gdf["구분"]) == {"주곡선"}
|
|
|
|
|
|
def test_with_cpg_unchanged(tmp_path):
|
|
gdf = _read(_sheet_zip(tmp_path, with_cpg=True))
|
|
assert sorted(gdf["등고수치"].tolist()) == [100.0, 105.0]
|
|
|
|
|
|
def test_merge_keys_carry_parser_version():
|
|
assert parser.PARSER_VERSION >= 2
|
|
for rel in (
|
|
"B04_PreProcess/B04_PreProcess_Engine.py",
|
|
"D03_PlanAnalysis/D03_PlanAnalysis_Terrain.py",
|
|
):
|
|
text = (ROOT / rel).read_text(encoding="utf-8")
|
|
assert '"parser": PARSER_VERSION' in text, rel
|