fix(B06): 암 경계 세션 오프셋을 자릿수 때문에 통째로 놓치던 것
세션에 저장하는 쪽(`createRockBoundaryStore`)은 키를 `toFixed(2)` 로 쓰는데 브라우저 재계산은 `toFixed(3)` 문자열로 찾아 **한 건도 못 읽었음**. 서버 경로는 키를 숫자로 바꿔 비교해 문제가 없었으므로 로컬 계산으로 옮기며 생긴 어긋남임. 키를 숫자로 되돌려 0.01m 단위로 맞춤. B06 에서 암 경계선을 올리내린 값이 이제 B05 유토곡선·횡단 면적에도 그대로 반영됨. 화면 검증(5173→5174, 같은 시점): B05 첫 진입 절토 4,774.1㎥ / 성토 16,690.7㎥, B06 도 같은 값(재계산 입력·결과 로그로 대조 — 측점 65, 샘플 65, 자연방토 25건까지 동일). B06 을 거치기 전과 후의 값 차이(성토 16,715.5 → 16,690.7)도 사라져 **첫 진입부터 일치**함. 진단용 임시 로그는 제거함. 전체 테스트 183건 통과, `tsc --noEmit` 통과. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -99,6 +99,30 @@ export async function refreshCrossDesigns(input: CrossRefreshInput): Promise<num
|
||||
return refreshFromServer(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 암 경계 세션 오프셋을 **자릿수에 안 휘둘리게** 읽는다.
|
||||
*
|
||||
* 저장하는 쪽(`createRockBoundaryStore`)은 키를 `toFixed(2)` 로 쓰고, 서버는 받은 키를
|
||||
* 숫자로 바꿔 비교했다. 로컬 계산이 문자열 키를 그대로 맞추려다 자릿수가 달라 세션값을
|
||||
* 통째로 놓쳤고, 그래서 B06 을 다녀오기 전과 후의 절·성토가 달랐다(2026-09-03 실측
|
||||
* 성토 16,715.5㎥ ↔ 16,690.7㎥). 키를 숫자로 되돌려 0.01m 단위로 맞춘다.
|
||||
*/
|
||||
function rockKey(chainageM: number): number {
|
||||
return Math.round(chainageM * 100) / 100;
|
||||
}
|
||||
|
||||
function readRockOffsets(projectId: string, routeId: number): Map<number, number> {
|
||||
const raw = readRockBoundarySession(projectId, routeId) ?? {};
|
||||
const offsets = new Map<number, number>();
|
||||
for (const [key, value] of Object.entries(raw)) {
|
||||
const chainage = Number(key);
|
||||
if (Number.isFinite(chainage) && typeof value === "number" && Number.isFinite(value)) {
|
||||
offsets.set(rockKey(chainage), value);
|
||||
}
|
||||
}
|
||||
return offsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* 브라우저 안에서 전 측점을 다시 계산한다(정상 경로).
|
||||
*
|
||||
@@ -127,7 +151,7 @@ function refreshLocally(input: CrossRefreshInput): number[] | null {
|
||||
toDesignProfile(alignment, detail.longitudinal.design_profiles?.[0]),
|
||||
];
|
||||
|
||||
const rockOffsets = readRockBoundarySession(projectId, input.routeId) ?? {};
|
||||
const rockOffsets = readRockOffsets(projectId, input.routeId);
|
||||
const rockDefault = readRockBoundaryDefault(projectId);
|
||||
|
||||
const updated: number[] = [];
|
||||
@@ -137,7 +161,7 @@ function refreshLocally(input: CrossRefreshInput): number[] | null {
|
||||
const design = previous as unknown as Record<string, unknown>;
|
||||
// 암 경계는 세션 조정값 → 저장분 → config 기본값 순 — 서버
|
||||
// `recompute_designs_for_alignment` 의 우선순위와 같다.
|
||||
const sessionOffset = rockOffsets[section.chainage_m.toFixed(3)];
|
||||
const sessionOffset = rockOffsets.get(rockKey(section.chainage_m));
|
||||
const storedOffset = design.rock_boundary_offset_m;
|
||||
const rockBoundaryOffsetM =
|
||||
typeof sessionOffset === "number"
|
||||
|
||||
Reference in New Issue
Block a user