diff --git a/resources/tester/helper_b05_station_roundtrip.cjs b/resources/tester/helper_b05_station_roundtrip.cjs index 381362f8..c31ff5cd 100644 --- a/resources/tester/helper_b05_station_roundtrip.cjs +++ b/resources/tester/helper_b05_station_roundtrip.cjs @@ -72,6 +72,10 @@ out.shown = [fields.station.value, fields.remainder.value]; out.untouched = fields.read(INTERVAL, true); fields.write(123.3721, INTERVAL); out.untouchedRaw = fields.read(INTERVAL, true); +// 사용자가 놓은 119.8 — 다시 열면 5 + 19.8 로 보이고 그대로 읽힘 +fields.write(119.8, INTERVAL); +out.r119 = [fields.station.value, fields.remainder.value, fields.read(INTERVAL, true)]; +fields.write(123.3721, INTERVAL); // 사용자가 잔여를 고치면 친 값으로 fields.remainder.value = "5.2"; fields.remainder.fire("change"); diff --git a/resources/tester/test_b05_station_roundtrip.py b/resources/tester/test_b05_station_roundtrip.py index 0bdbd305..e0f84139 100644 --- a/resources/tester/test_b05_station_roundtrip.py +++ b/resources/tester/test_b05_station_roundtrip.py @@ -34,6 +34,7 @@ def test_칸을_안_고치면_실어_둔_측점_그대로(results): assert results["untouched"] == 123.37 assert results["untouchedRaw"] == 123.3721 assert results["retypedSame"] == 123.37 + assert results["r119"] == ["5", "19.8", 119.8] def test_칸을_고치면_친_값(results): @@ -49,3 +50,54 @@ def test_계획고_편집은_가까운_새_측점으로_옮김(results): } # 옮길 곳이 없으면 종전대로 지움 assert "200.000" not in results["deleted"]["station_offsets"] + + +# ── 서버 — 사용자가 놓은 구조물 측점은 소수 그대로(격자 붙이기는 횡단 측점에만) ───────── +# 브레인 판정(다): 횡단 측점 · 파일 이름의 정수 m 격자 붙이기는 그대로 두고, 구조물 정본 측점만 +# 사용자가 놓은 소수 그대로 저장 · 다시 읽기. 임시 storage 에서만 씀(공유 storage 안 건드림). + + +def _flat_sampler(): + import numpy as np + + class _Flat: + def sample_xy(self, xy): + count = len(np.asarray(xy, dtype=np.float64)) + return np.full(count, 100.0), np.ones(count, dtype=bool) + + return _Flat() + + +def test_사용자_구조물_119_8_저장_다시_읽기_그대로(tmp_path): + from B05_Profile.B05_Profile_Engine_Sections import cross_filename, resolve_extra_stations + from B05_Profile.B05_Profile_Engine_Sections_Core import ( + SectionGenerationOptions, + generate_sections, + ) + from B05_Profile.B05_Profile_Structures_Repository import load_structures, save_structures + from B05_Profile.B05_Profile_Structures_Schema import StructureInstance + + item = StructureInstance( + type_id="cross_drain_exposed", + placement="point", + chainage_m=119.8, + memo="메모만", + placement_source="manual", + ) + save_structures(str(tmp_path), [item], base_revision=0) + _, loaded = load_structures(str(tmp_path)) + assert [s.chainage_m for s in loaded] == [119.8] + + extras = resolve_extra_stations(tmp_path, []) + assert [chainage for chainage, _ in extras] == [119.8] + sections = generate_sections( + [[0.0, 0.0, 100.0], [300.0, 0.0, 100.0]], + _flat_sampler(), + SectionGenerationOptions(extra_stations=extras), + ) + chainages = [round(s["chainage_m"], 3) for s in sections["longitudinal"]["stations"]] + # 횡단 측점은 격자 120 으로 붙음(파일 이름 cross_00120m 한 장) — 정본 측점은 119.8 그대로 + assert 120.0 in chainages and 119.8 not in chainages + assert cross_filename(119.8) == cross_filename(120.0) + _, again = load_structures(str(tmp_path)) + assert [s.chainage_m for s in again] == [119.8] and again[0].memo == "메모만"