fix(B05): 구조물 측점 계획고 편집이 가짜 변화점을 만들던 것 — 정본 누가거리 일원화

사용자 보고(2026-09-04) — 배수관 2 자리에서 계획선이 수직으로 꺾이고 최대 기울기가
**155,791 %**. 원인은 「가까운 점」이 아니라 **한 구조물이 층마다 다른 누가거리를 든 것**:
  횡단 측점 264.054626 · 종단 정본 변화점 264.055 · 배수 정본 파일 **264.06**(cm 반올림).
사이드 목록이 든 264.06 으로 계획고를 편집하면 정본 옆 5mm 자리에 변화점이 하나 더 서고,
둘 사이 종단곡선이 mm 로 쭈그러들어 기울기가 거리 0 에 가까운 값으로 나뉘었음.
2026-09-03 에 ▲▼ 버튼 경로만 막아 뒀고(같은 증상 11,858%), 측점 테이블·도구 경로가 남아
다시 터진 것.

- **저장**(`common_util_drainage_pipes.py`) — 누가거리를 좌표(x·y)와 같은 **밀리미터 기준**으로
  남김(cm 반올림 제거). 종단 정본 변화점(3자리)과 값이 어긋나지 않음.
- **화면**(`_UI_Profile_Panel.ts`) — 구조물 측점 목록이 들어오는 **한 자리**에서 종단 정본
  측점(0.1m 안)으로 누가거리를 갈아 끼움. 버튼·테이블·도구 **모든 편집 경로**가 함께 막힘.
  이미 cm 로 저장된 옛 프로젝트도 이 경로로 안전해짐.

자체검증(공용 브라우저 임시 탭):
① 264 부근 그래프 측점이 **264.055 하나**로 모임(고치기 전 264.06 이 따로 있었음)
② 그 구조물 측점 계획고를 8칸 올려도 **수직 꺾임 0건**, 계획선 점 수 1,208 불변,
   최대 기울기 66.0 → 183.5%(8칸 올린 만큼의 정상값. 고치기 전 155,791%)
③ 전체 시험 381 통과·17 건너뜀.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 23:33:32 +09:00
co-authored by Claude Opus 5
parent 4a57272e72
commit 5446f0cfd9
2 changed files with 39 additions and 2 deletions
+34 -1
View File
@@ -85,6 +85,9 @@ const MAX_PANEL_HEIGHT_RATIO = 0.9;
* 계산이 브라우저 안에서 끝나면서(2026-09-03) 서버 왕복이 사라져 250→60ms 로 줄였다 — * 계산이 브라우저 안에서 끝나면서(2026-09-03) 서버 왕복이 사라져 250→60ms 로 줄였다 —
* 실측 전 측점(128) 재계산 7.5ms 라 손을 떼는 즉시 유토곡선이 따라온다. */ * 실측 전 측점(128) 재계산 7.5ms 라 손을 떼는 즉시 유토곡선이 따라온다. */
const CROSS_PREVIEW_DEBOUNCE_MS = 60; const CROSS_PREVIEW_DEBOUNCE_MS = 60;
/** 구조물 측점을 종단 정본 측점으로 맞춰 주는 허용 오차(m). 층마다 반올림이 달라 생기는
* mm~cm 어긋남만 흡수할 크기다 — 이보다 멀면 서로 다른 측점이다. */
const STATION_SNAP_TOLERANCE_M = 0.1;
/** /**
* 저장된 계획선 선형을 읽되 **모양을 먼저 검증한다**. * 저장된 계획선 선형을 읽되 **모양을 먼저 검증한다**.
@@ -341,6 +344,36 @@ export function createRouteProfilePanel(
세로는 보이는 구간에 맞춰 자동이라 사람이 맞출 것이 없다(2026-09-04 사용자 확정). */ 세로는 보이는 구간에 맞춰 자동이라 사람이 맞출 것이 없다(2026-09-04 사용자 확정). */
const profileZoom = createProfileZoom(() => draw()); const profileZoom = createProfileZoom(() => draw());
/**
* 구조물 측점의 누가거리를 **종단 정본 값으로 갈아 끼운다**(2026-09-04).
*
* 같은 구조물이 층마다 다른 누가거리를 들고 있었다 — 횡단 측점 `264.054626`,
* 종단 정본 변화점 `264.055`, 배수 정본 파일 `264.06`(cm 반올림). 사이드 목록이 든
* 값으로 계획고를 편집하면 정본 옆 mm 자리에 **가짜 변화점**이 하나 더 서고, 둘 사이
* 종단곡선이 mm 로 쭈그러들어 기울기가 155,791% 로 튀었다(2026-09-04 사용자 보고).
*
* 2026-09-03 에 ▲▼ 버튼 경로만 막았는데 측점 테이블·도구 경로가 남아 다시 터졌다.
* 값이 화면에 들어오는 **이 한 자리**에서 정본으로 맞춰 모든 경로를 함께 막는다.
*/
function snapToMasterStations(stations: IrregularStation[]): IrregularStation[] {
const master = alignment?.stations;
if (!master?.length) return stations;
return stations.map((station) => {
let best: number | null = null;
let gap = STATION_SNAP_TOLERANCE_M;
for (const node of master) {
const distance = Math.abs(node.chainage_m - station.chainage_m);
if (distance <= gap) {
gap = distance;
best = node.chainage_m;
}
}
return best === null || best === station.chainage_m
? station
: { ...station, chainage_m: best };
});
}
/** 세로 자동 맞춤이 지금 쓰는 Y 창. 계획고를 끄는 동안에는 이 값을 붙잡는다. */ /** 세로 자동 맞춤이 지금 쓰는 Y 창. 계획고를 끄는 동안에는 이 값을 붙잡는다. */
let elevationWindow: { min: number; max: number } | undefined; let elevationWindow: { min: number; max: number } | undefined;
/** 세로 창을 **다시 그리지 않고** 옮기는 갱신기 — 그릴 때마다 렌더러가 새로 준다. */ /** 세로 창을 **다시 그리지 않고** 옮기는 갱신기 — 그릴 때마다 렌더러가 새로 준다. */
@@ -652,7 +685,7 @@ export function createRouteProfilePanel(
}, },
/** 비정규 측점 목록을 반영해 그래프(세로선+라벨)·테이블(주석)을 다시 그린다. */ /** 비정규 측점 목록을 반영해 그래프(세로선+라벨)·테이블(주석)을 다시 그린다. */
setIrregularStations(stations: IrregularStation[]) { setIrregularStations(stations: IrregularStation[]) {
irregularStations = stations; irregularStations = snapToMasterStations(stations);
draw(); draw();
}, },
/** 구조물 타입 레지스트리를 받아 마크 색·약호·우클릭 메뉴에 쓴다(최초 1회). */ /** 구조물 타입 레지스트리를 받아 마크 색·약호·우클릭 메뉴에 쓴다(최초 1회). */
+5 -1
View File
@@ -90,7 +90,11 @@ class PipePoint:
def as_dict(self) -> dict[str, Any]: def as_dict(self) -> dict[str, Any]:
# 구 형식 저장분이 확장 필드 없이 그대로 다시 저장되도록 기본값은 생략한다. # 구 형식 저장분이 확장 필드 없이 그대로 다시 저장되도록 기본값은 생략한다.
payload: dict[str, Any] = { payload: dict[str, Any] = {
"chainage_m": round(float(self.chainage_m), 2), # 누가거리는 좌표(x·y)와 **같은 밀리미터 기준**으로 남긴다. cm 로 반올림하던
# 옛 규칙은 종단 정본 변화점(3자리)과 최대 5mm 어긋났고, 그 값으로 계획고를
# 편집하면 정본 옆 mm 자리에 가짜 변화점이 하나 더 서서 종단곡선이 mm 로
# 쭈그러들었다 — 그 구간 기울기가 155,791% 로 튀었다(2026-09-04 사용자 보고).
"chainage_m": round(float(self.chainage_m), 3),
"source": self.source, "source": self.source,
} }
if self.facility != PIPE_FACILITY_PIPE: if self.facility != PIPE_FACILITY_PIPE: