feat(500-2 측점선 띠): B05 종단 — 원지반선 ±12 px 띠 안 측점선 = 임시 횡단 먼저(표시 · 누름 같은 판정) · 띠 밖 측점선 = 측점 고름

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 20:13:50 +09:00
co-authored by Claude Sonnet 5.5
parent d790466e6c
commit 80127fdd57
5 changed files with 75 additions and 41 deletions
+9 -5
View File
@@ -1,7 +1,7 @@
"""490-1 B05 종단 — 임시 횡단이 열리는 자리 가까이 표시 = 누름과 같은 판정(`crossPickAt`).
판정 함수 = 옛 누름 판정(원지반선 위아래 12 px · 500-1 8 → 12 · 정수 m · 추가 측점 선 = 그 측점 · 측점선 · 단추 = null)과
같은 값 · 허용 밖 null. TS 쪽 = `helper_490_1_cross_pick.cjs`(Node). 화면 조작은 ORCA 로 확인.
판정 함수 = 옛 누름 판정(원지반선 위아래 12 px · 500-1 8 → 12 · 정수 m · 추가 측점 선 = 그 측점 · 단추 = null)과
같은 값 · 허용 밖 null. 500-2 = 다른 측점선("station")은 띠 안이면 임시 횡단 · 띠 밖이면 null(측점 고름 몫). TS 쪽 = `helper_490_1_cross_pick.cjs`(Node). 화면 조작은 ORCA 로 확인.
"""
from __future__ import annotations
@@ -30,7 +30,7 @@ def _old_pick(hit, chainage: float, pointer_y: float) -> int | None:
"""옛 `groundPickAt` + 누름 처리(Render.ts 329~346) 그대로."""
if hit == "other":
return None
if hit:
if isinstance(hit, dict):
return round(hit["plusM"])
valid = [s for s in SAMPLES if s["elevation_m"] is not None]
after = next((i for i, s in enumerate(valid) if s["chainage_m"] >= chainage), -1)
@@ -51,7 +51,11 @@ CASES = [
{"hit": None, "chainageM": 0.0, "pointerY": 80.0}, # 첫 표본 = null(옛 판정 그대로)
{"hit": None, "chainageM": 70.0, "pointerY": 100.0}, # 끝 뒤
{"hit": {"plusM": 33.6}, "chainageM": 10.0, "pointerY": 0.0}, # 추가 측점 선
{"hit": "other", "chainageM": 10.4, "pointerY": 70.0}, # 측점선 · 단추
{"hit": "other", "chainageM": 10.4, "pointerY": 70.0}, # 단추
{"hit": "station", "chainageM": 10.4, "pointerY": 69.0}, # 측점선 · 띠 안 = 임시 횡단
{"hit": "station", "chainageM": 10.4, "pointerY": 81.0}, # 측점선 · 띠 끝 안
{"hit": "station", "chainageM": 10.4, "pointerY": 90.0}, # 측점선 · 띠 밖 = 측점 고름
{"hit": "station", "chainageM": 0.0, "pointerY": 80.0}, # 측점선 · 첫 표본 = null
]
@@ -75,7 +79,7 @@ def test_판정_함수_옛_누름과_같은_값() -> None:
assert result["slack"] == 12
picks = [row["pick"] for row in result["out"]]
assert picks == [_old_pick(c["hit"], c["chainageM"], c["pointerY"]) for c in CASES]
assert picks == [10, 10, None, None, 50, None, None, 34, None]
assert picks == [10, 10, None, None, 50, None, None, 34, None, 10, 10, None, None]
def test_누름_표시_같은_길() -> None:
@@ -78,3 +78,18 @@ def test_제목_줄_끌기_화면_안() -> None:
assert "innerWidth" in drag and "innerHeight" in drag # 화면 밖 안 나감
assert "root.parentElement!.getBoundingClientRect()" in drag # 종단 칸 안
assert "refit();" in modal # 다시 열 때 가둠
def test_500_2_측점선_띠_안_임시_횡단_먼저() -> None:
modal = _read("B05_Profile", "B05_Profile_UI_Profile_CrossModal.ts")
# 단추 = other 먼저 · 추가 측점선 = plusM · 그 밖 측점선 = station(띠 안이면 임시 횡단)
flat = " ".join(modal.split())
assert 'target.closest("button") ? "other" : marker ? "station" : null' in flat
logic = _read("B05_Profile", "logic", "B05_Profile_Profile_CrossPick.ts")
assert '"station"' in logic and 'input.hit === "other"' in logic
# 누름 = 잡는 단계에서 띠 안 측점선의 자기 고름을 막고 임시 횡단을 엶
render = _read("B05_Profile", "B05_Profile_UI_Profile_Render.ts")
start = render.index("// 잡는 단계(capture)")
click = render[start : render.index("const derived = deriveProfile", start)]
assert "event.stopPropagation()" in click and "openCrossModal(" in click
assert " ".join(click.split()).endswith("}, true, );")