fix(B05·B06): 한 자리 측점 둘 숨음 — 측점 0.006 m 안 꼭짓점 · 편집 키를 그 측점으로 모음(213-1)
- 까닭: 자동설계 관 측점 263.206 → 화면 저장 0.01 m 반올림 263.21 로 측점이 다시 섬 · 계획선 꼭짓점 · 편집 키는 옛 글자 그대로 → 새 측점 편집과 0.004 m 사이 두 꼭짓점(−15003% 계단 · 엄상준_검증 No.13+3) - 계획선 공용 함수 짝(파이썬 snap_to_stations ↔ TS snapToStations) — 측점 위 것이 이김 · 옮긴 꼭짓점은 옛 선의 측점 높이(측점 계획고 그대로) · 양 끝 · 측점에서 먼 키는 그대로 · 읽을 때 · [저장] 때 모두 정리 - 192 병합(_follow_moved_stations)도 옛 측점 0.006 m 안 글자를 같은 측점으로 봄 - 시험 test_213_1(합성 · 거울 · 엄상준 사본 재현) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F3mdb91125mPoC6tpsQx4P
This commit is contained in:
@@ -158,6 +158,62 @@ def tangent_elevation(pvi_s: np.ndarray, pvi_z: np.ndarray, targets: np.ndarray)
|
||||
return np.interp(targets, pvi_s, pvi_z)
|
||||
|
||||
|
||||
#: 반올림만 다른 같은 측점(m) — 관 측점 0.001m(자동설계) ↔ 0.01m(화면 저장) 차이.
|
||||
#: 화면 `SAME_STATION_SNAP_M`(B05_Profile_UI_Profile_Alignment.ts) 와 짝.
|
||||
SAME_STATION_SNAP_M = 0.006
|
||||
|
||||
|
||||
def _nearest_station(value: float, station_s: np.ndarray) -> float | None:
|
||||
if not station_s.size:
|
||||
return None
|
||||
near = float(station_s[int(np.argmin(np.abs(station_s - value)))])
|
||||
return near if abs(near - value) < SAME_STATION_SNAP_M else None
|
||||
|
||||
|
||||
def snap_to_stations(
|
||||
base_s: np.ndarray,
|
||||
base_z: np.ndarray,
|
||||
edits: dict[str, dict[str, float]],
|
||||
station_s: np.ndarray,
|
||||
) -> tuple[np.ndarray, np.ndarray, dict[str, dict[str, float]]]:
|
||||
"""측점 0.006m 안의 꼭짓점(base_pvi) · 편집 키를 그 측점으로 모은다(213-1).
|
||||
|
||||
관 측점이 반올림으로 옮겨도(263.206 → 263.21) 꼭짓점 · 편집 키는 옛 글자로 남아, 새 측점
|
||||
편집과 0.004m 사이 두 꼭짓점이 됨(−15000% 계단 · 숨은 측점). 겹치면 측점 위 것이 이김.
|
||||
옮긴 꼭짓점은 옛 선의 측점 높이를 받아 측점 계획고가 안 바뀜. 양 끝 · 측점에서 먼 키는 그대로.
|
||||
"""
|
||||
last = len(base_s) - 1
|
||||
nodes: dict[float, tuple[float, float, float]] = {}
|
||||
for index, (s, z) in enumerate(zip(base_s.tolist(), base_z.tolist())):
|
||||
near = None if index in (0, last) else _nearest_station(s, station_s)
|
||||
at = s if near is None else near
|
||||
gap = 0.0 if near is None else abs(near - s)
|
||||
slot = round(at, _KEY_DECIMALS)
|
||||
if slot not in nodes or gap < nodes[slot][0]:
|
||||
# 옮긴 꼭짓점 높이 = 옛 선의 그 측점 높이 — 측점 계획고가 그대로
|
||||
nodes[slot] = (gap, at, z if near is None else float(np.interp(at, base_s, base_z)))
|
||||
ordered = [nodes[slot] for slot in sorted(nodes)]
|
||||
snapped: dict[str, dict[str, float]] = {}
|
||||
for name, values in edits.items():
|
||||
best: dict[str, tuple[float, float]] = {}
|
||||
for key, value in values.items():
|
||||
try:
|
||||
chainage = float(key)
|
||||
except (TypeError, ValueError):
|
||||
chainage = float("nan")
|
||||
near = _nearest_station(chainage, station_s) if np.isfinite(chainage) else None
|
||||
target = key if near is None else chainage_key(near)
|
||||
gap = 0.0 if near is None else abs(near - chainage)
|
||||
if target not in best or gap < best[target][0]:
|
||||
best[target] = (gap, value)
|
||||
snapped[name] = {key: value for key, (_, value) in best.items()}
|
||||
return (
|
||||
np.array([item[1] for item in ordered], dtype=np.float64),
|
||||
np.array([item[2] for item in ordered], dtype=np.float64),
|
||||
snapped,
|
||||
)
|
||||
|
||||
|
||||
def resolve_pvi(
|
||||
base_s: np.ndarray,
|
||||
base_z: np.ndarray,
|
||||
@@ -407,6 +463,22 @@ def build_alignment(
|
||||
if value is not None
|
||||
}
|
||||
|
||||
station_s = np.array(
|
||||
sorted(
|
||||
float(station["chainage_m"])
|
||||
for station in stations
|
||||
if isinstance(station.get("chainage_m"), (int, float))
|
||||
),
|
||||
dtype=np.float64,
|
||||
)
|
||||
base_s, base_z, snapped = snap_to_stations(
|
||||
base_s,
|
||||
base_z,
|
||||
{"station_offsets": station_offsets, "curve_radii": curve_radii},
|
||||
station_s,
|
||||
)
|
||||
station_offsets, curve_radii = snapped["station_offsets"], snapped["curve_radii"]
|
||||
|
||||
pvi_s, pvi_z, sources = resolve_pvi(base_s, base_z, station_offsets)
|
||||
curves, warnings = build_curves(
|
||||
pvi_s, pvi_z, policy, curve_radii, only_explicit=only_explicit_curves
|
||||
|
||||
Reference in New Issue
Block a user