feat(횡단초안): 344-3 측점 열쇠 — 세션 횡단 초안을 측점 열쇠로 · 옛 초안 옮김 · 노선 바뀜 넘김 · 노선 밖 고침 알림
- 열쇠 규칙 한 벌 = common_util_station_key(ts · py 짝 · 거울 시험) — 일반 grid:k · 관 pipe:<id> · 구조물 structure:<id> · 시종점 end:BP/EP · id 모름 at:<0.01 m> - 세션 칸 다섯(카드 선택 · 노견 확장 · 소단 깊이 · 암 경계 · 암 경사) = 측점 열쇠로 담음 · 부르는 쪽은 그대로 누가거리로 읽고 씀 · 칸마다 쓴 때 자리를 함께 담아 구조물 id 를 아직 모를 때도 그 측점 고침을 읽음 - 옛 초안(누가거리 열쇠)은 읽을 때 측점 열쇠로 옮김 · 지금 측점에 없는 고침은 지우지 않고 남김 - 측점 목록 = 상세가 초안 측점을 얹을 때 · 다시 셈 때 세움(관 id = 관 장부 · 구조물 id = 측점 계획 · 구조물 목록) - 노선 바뀜 넘김 carryStationDrafts — 카드 선택 넷(지반 유형 · 측구 종류 · 측구 선택 · 2단 경사) · 암 경계 · 암 경사만 · 단면 유형 · 측구 방향은 새 지형이 정함 · 사라진 측점 = 「노선 밖 고침 N 건」 한 줄(부르는 자리 = 3파) - 옛 시험 셋 새 창구로 맞춤 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfHKQs7J3hQELKMWQMUJEy
This commit is contained in:
@@ -65,6 +65,8 @@ const drafts = loadTs("B06_Section/B06_Section_Section_Drafts.ts", {
|
||||
}
|
||||
},
|
||||
},
|
||||
// 측점 열쇠 세우기(344-3) — 이 시험 몫 아님
|
||||
"./B06_Section_Station_Keys": { useStationKeys: () => {}, useStationOwners: () => {} },
|
||||
"./B06_Section_Api_Fetch": {
|
||||
previewStructureSections: async (_projectId, chainages) => {
|
||||
asked.push(chainages);
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""344-3 측점 열쇠 거울 — `common_util_station_key.py` ↔ `common_util_station_key.ts` 같은 열쇠.
|
||||
|
||||
일반 grid:k(누가거리 ÷ 간격 반올림 · 0.5 는 위로) · 관 pipe:<id> · 구조물 structure:<id> ·
|
||||
시종점 end:BP/EP · id 모름 at:<0.01 m> · 옛 열쇠(누가거리 글) · at: 의 누가거리.
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
||||
if str(PROJECT_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from common_util.common_util_station_key import ( # noqa: E402
|
||||
chainage_key,
|
||||
loose_chainage,
|
||||
station_key,
|
||||
)
|
||||
|
||||
TS = PROJECT_ROOT / "common_util" / "common_util_station_key.ts"
|
||||
TYPESCRIPT = PROJECT_ROOT / "config" / "node_modules" / "typescript"
|
||||
|
||||
CASES = [
|
||||
("bp", 0.0, 20.0, None, "structure"),
|
||||
("ep", 812.345, 20.0, None, "structure"),
|
||||
("regular", 40.0, 20.0, None, "structure"),
|
||||
("regular", 50.0, 20.0, None, "structure"), # 2.5 → 3(위로)
|
||||
("regular", 69.996, 20.0, None, "structure"),
|
||||
("regular", 40.0, None, None, "structure"),
|
||||
("irregular", 85.054, 20.0, "pipe-s3", "pipe"),
|
||||
("irregular", 85.054, 20.0, "st-7", "structure"),
|
||||
("irregular", 85.054, 20.0, None, "structure"),
|
||||
("irregular", 1.005, 20.0, None, "structure"),
|
||||
("pipe", 12.344, 20.0, "pipe-s1", "structure"),
|
||||
("structure", 12.345, 20.0, None, "structure"),
|
||||
]
|
||||
LOOSE = ["85.05", "at:85.05", "grid:4", "pipe:pipe-s3", "-1.5", "end:BP"]
|
||||
|
||||
SCRIPT = r"""
|
||||
const ts = require(process.argv[1]);
|
||||
const fs = require("fs");
|
||||
const src = fs.readFileSync(process.argv[2], "utf8");
|
||||
const opts = { compilerOptions: { module: ts.ModuleKind.CommonJS } };
|
||||
const js = ts.transpileModule(src, opts).outputText;
|
||||
const box = { exports: {} };
|
||||
new Function("exports", "module", js)(box.exports, box);
|
||||
const m = box.exports;
|
||||
const input = JSON.parse(process.argv[3]);
|
||||
process.stdout.write(JSON.stringify({
|
||||
keys: input.cases.map((c) => m.stationKey(c[0], c[1], c[2], c[3], c[4])),
|
||||
chainage: input.cases.map((c) => m.chainageKey(c[1])),
|
||||
loose: input.loose.map((k) => m.looseChainage(k)),
|
||||
}));
|
||||
"""
|
||||
|
||||
|
||||
def test_파이썬과_TS_열쇠_같음():
|
||||
proc = subprocess.run(
|
||||
[
|
||||
"node",
|
||||
"-e",
|
||||
SCRIPT,
|
||||
str(TYPESCRIPT),
|
||||
str(TS),
|
||||
json.dumps({"cases": CASES, "loose": LOOSE}),
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
timeout=60,
|
||||
)
|
||||
assert proc.returncode == 0, proc.stderr
|
||||
out = json.loads(proc.stdout)
|
||||
assert out["keys"] == [station_key(*case) for case in CASES]
|
||||
assert out["chainage"] == [chainage_key(case[1]) for case in CASES]
|
||||
assert out["loose"] == [loose_chainage(key) for key in LOOSE]
|
||||
|
||||
|
||||
def test_열쇠_규칙():
|
||||
assert station_key("bp", 0.0, 20.0) == "end:BP"
|
||||
assert station_key("ep", 812.3, 20.0) == "end:EP"
|
||||
assert station_key("regular", 50.0, 20.0) == "grid:3"
|
||||
assert station_key("irregular", 85.054, 20.0, "pipe-s3", "pipe") == "pipe:pipe-s3"
|
||||
assert station_key("irregular", 85.054, 20.0) == "at:85.05"
|
||||
assert loose_chainage("85.05") == 85.05 and loose_chainage("grid:4") is None
|
||||
@@ -64,7 +64,8 @@ def test_등록표_밖에서_날문자열_세션_키를_안_쓴다():
|
||||
def test_옛_암경계_키가_코드에_안_남아_있다():
|
||||
"""실사고 자리 못박기 — 읽는 쪽이 등록표를 거치는지."""
|
||||
persist = (ROOT / "B06_Section" / "B06_Section_UI_Page_Persist.ts").read_text(encoding="utf-8")
|
||||
assert 'readState<Record<string, number>>("rockb"' in persist, "등록표를 안 거침"
|
||||
# 344-3 — 측점 열쇠 창구(readKeyed → 등록표 readState)로 읽음
|
||||
assert 'readKeyed<number>("rockb", projectId, routeId)' in persist, "등록표를 안 거침"
|
||||
# 옛 키가 **코드로** 되살아나는 것만 막는다 — 주석에 사연으로 적힌 것은 남겨 둔다.
|
||||
code = "\n".join(
|
||||
line for line in persist.splitlines() if not line.lstrip().startswith(("*", "//", "/*"))
|
||||
|
||||
@@ -202,7 +202,8 @@ def test_암경계선은_등록표_키로_읽는다():
|
||||
persist = (PROJECT_ROOT / "B06_Section" / "B06_Section_UI_Page_Persist.ts").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
assert 'readState<Record<string, number>>("rockb"' in persist
|
||||
# 344-3 — 측점 열쇠 창구(readKeyed → 등록표 readState)로 읽음
|
||||
assert 'readKeyed<number>("rockb", projectId, routeId)' in persist
|
||||
|
||||
|
||||
# ── ⑦ 저장된 표준 횡단면이 새 탭에서 안 서던 것 (`72e50b3e`) ───────────────────
|
||||
|
||||
Reference in New Issue
Block a user