refactor(472-5 5-D 나눔): 측점 조정창 제어 687 줄 → 저장 묶음 접기 넷(4축 · 연동 · 단 수 · 단별 구간)을 Link_Session 으로 · 646 줄 · 동작 같음
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
* 검증 → 담기 / 쓰기 → 통째 직렬화)이라 제어기마다 짝을 두던 것을 하나로 모았다.
|
||||
* ========================================================================== */
|
||||
|
||||
import type { CrossSection } from "./B06_Section_Api_Fetch";
|
||||
import type { CrossSection, StoredWallSpan } from "./B06_Section_Api_Fetch";
|
||||
import type { RevetKey } from "./B06_Section_UI_Cross_Culvert";
|
||||
import type { WallAdjust } from "./B06_Section_UI_Cross_Culvert_Types";
|
||||
import {
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
type InletStructureControl,
|
||||
type RevetLinkControl,
|
||||
type RevetOffsetControl,
|
||||
type SpanValues,
|
||||
} from "./B06_Section_UI_Cross_Culvert_Wire";
|
||||
import { culvertCardState } from "./B06_Section_UI_Cross_View_Structure";
|
||||
import type { PipeRevetChoice } from "../A00_Common/design/design_structure_pipe_calc";
|
||||
@@ -156,6 +157,73 @@ export function createLinkFlagSession(sessionKey: () => string | null): LinkFlag
|
||||
};
|
||||
}
|
||||
|
||||
/* ── 확정 · 임시저장 payload — 세션 키(누가거리 · `:역할` · `b` 앞머리)를 측점별로 되접음 ── */
|
||||
type Each<V> = Pick<ReadonlyMap<string, V>, "forEach">;
|
||||
|
||||
/** 측점별 기슭막이 4축 조작값(역할 → 값 · null = 되돌림). */
|
||||
export function foldRevetAdjusts(
|
||||
shifts: Each<WallAdjust | null>,
|
||||
): Map<number, Record<string, WallAdjust | null>> {
|
||||
const result = new Map<number, Record<string, WallAdjust | null>>();
|
||||
shifts.forEach((adjust, key) => {
|
||||
const [chainage, role] = key.split(":");
|
||||
const value = Number(chainage);
|
||||
if (!Number.isFinite(value) || !role) return;
|
||||
const bucket = result.get(value) ?? {};
|
||||
bucket[role] = adjust;
|
||||
result.set(value, bucket);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/** 측점별 연동 해제 · 종단경사 반영 플래그. */
|
||||
export function foldLinkFlags(
|
||||
detachedFlags: Each<boolean>,
|
||||
gradeFlags: Each<boolean>,
|
||||
): Map<number, { detached?: boolean; followGrade?: boolean }> {
|
||||
const result = new Map<number, { detached?: boolean; followGrade?: boolean }>();
|
||||
const put = (key: string, patch: { detached?: boolean; followGrade?: boolean }): void => {
|
||||
const value = Number(key);
|
||||
if (!Number.isFinite(value)) return;
|
||||
result.set(value, { ...(result.get(value) ?? {}), ...patch });
|
||||
};
|
||||
detachedFlags.forEach((detached, key) => put(key, { detached }));
|
||||
gradeFlags.forEach((followGrade, key) => put(key, { followGrade }));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** 측점별 다단 단 수 — 세션에 있는 쪽만 · 없는 쪽은 바탕(캐시 설계) 값 그대로(445 H3 · `mergeCrossPatches`). */
|
||||
export function foldExtraCounts(
|
||||
counts: Each<number>,
|
||||
): Map<number, Partial<{ outlet: number; basin: number }>> {
|
||||
const result = new Map<number, Partial<{ outlet: number; basin: number }>>();
|
||||
counts.forEach((count, key) => {
|
||||
const basin = key.startsWith("b");
|
||||
const value = Number(basin ? key.slice(1) : key);
|
||||
if (!Number.isFinite(value)) return;
|
||||
const bucket = result.get(value) ?? {};
|
||||
bucket[basin ? "basin" : "outlet"] = count;
|
||||
result.set(value, bucket);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/** 측점별 다단 단별 구간값. */
|
||||
export function foldExtraSpans(
|
||||
spans: Each<SpanValues>,
|
||||
): Map<number, Record<string, StoredWallSpan>> {
|
||||
const result = new Map<number, Record<string, StoredWallSpan>>();
|
||||
spans.forEach((value, key) => {
|
||||
const [chainage, wall] = key.split(":");
|
||||
const chainageM = Number(chainage);
|
||||
if (!Number.isFinite(chainageM) || !wall) return;
|
||||
const bucket = result.get(chainageM) ?? {};
|
||||
bucket[wall] = { length_m: value.lengthM, before_m: value.beforeM, after_m: value.afterM };
|
||||
result.set(chainageM, bucket);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 연동을 푸는 순간(카드 [연동] · 좌측 [연동] 둘 다 · 139-2) — 그 카드가 그리던 벽마다 4축을 이
|
||||
* 측점 값으로 굳힘: 위치(x · d) = 소유 측점 적용값(물려받던 값) · 높이 · 형태 = 그 카드가 그린 값.
|
||||
|
||||
@@ -29,6 +29,10 @@ import { createBodyControls } from "./B06_Section_UI_Page_Ford_Controls";
|
||||
import {
|
||||
createLinkFlagSession,
|
||||
createSessionMap,
|
||||
foldExtraCounts,
|
||||
foldExtraSpans,
|
||||
foldLinkFlags,
|
||||
foldRevetAdjusts,
|
||||
freezeLinkedWalls,
|
||||
} from "./B06_Section_UI_Page_Link_Session";
|
||||
import { createSpanControl } from "./B06_Section_UI_Page_Span_Control";
|
||||
@@ -613,56 +617,11 @@ export function createStationControls(deps: StationControlDeps): StationControls
|
||||
widths: stationWidths,
|
||||
inletStructures,
|
||||
basinAdjustments,
|
||||
// 확정·임시저장 payload용 — 세션 키(누가거리:역할)를 측점별로 되접는다.
|
||||
revetAdjustsByChainage: () => {
|
||||
const result = new Map<number, Record<string, WallAdjust | null>>();
|
||||
revetShifts.forEach((adjust, key) => {
|
||||
const [chainage, role] = key.split(":");
|
||||
const value = Number(chainage);
|
||||
if (!Number.isFinite(value) || !role) return;
|
||||
const bucket = result.get(value) ?? {};
|
||||
bucket[role] = adjust;
|
||||
result.set(value, bucket);
|
||||
});
|
||||
return result;
|
||||
},
|
||||
// 확정 payload용 — 측점별 연동 해제·종단경사 반영 플래그.
|
||||
linkFlagsByChainage: () => {
|
||||
const result = new Map<number, { detached?: boolean; followGrade?: boolean }>();
|
||||
const put = (key: string, patch: { detached?: boolean; followGrade?: boolean }): void => {
|
||||
const value = Number(key);
|
||||
if (!Number.isFinite(value)) return;
|
||||
result.set(value, { ...(result.get(value) ?? {}), ...patch });
|
||||
};
|
||||
linkDetached.forEach((detached, key) => put(key, { detached }));
|
||||
followGrades.forEach((followGrade, key) => put(key, { followGrade }));
|
||||
return result;
|
||||
},
|
||||
extraCountsByChainage: () => {
|
||||
// 세션에 있는 쪽만 — 없는 쪽은 바탕(캐시 설계) 값 그대로(445 H3 · `mergeCrossPatches`)
|
||||
const result = new Map<number, Partial<{ outlet: number; basin: number }>>();
|
||||
extraCounts.forEach((count, key) => {
|
||||
const basin = key.startsWith("b");
|
||||
const value = Number(basin ? key.slice(1) : key);
|
||||
if (!Number.isFinite(value)) return;
|
||||
const bucket = result.get(value) ?? {};
|
||||
bucket[basin ? "basin" : "outlet"] = count;
|
||||
result.set(value, bucket);
|
||||
});
|
||||
return result;
|
||||
},
|
||||
extraSpansByChainage: () => {
|
||||
const result = new Map<number, Record<string, StoredWallSpan>>();
|
||||
extraSpans.forEach((value, key) => {
|
||||
const [chainage, wall] = key.split(":");
|
||||
const chainageM = Number(chainage);
|
||||
if (!Number.isFinite(chainageM) || !wall) return;
|
||||
const bucket = result.get(chainageM) ?? {};
|
||||
bucket[wall] = { length_m: value.lengthM, before_m: value.beforeM, after_m: value.afterM };
|
||||
result.set(chainageM, bucket);
|
||||
});
|
||||
return result;
|
||||
},
|
||||
// 확정·임시저장 payload용 — 세션 키를 측점별로 되접음(`_Link_Session`)
|
||||
revetAdjustsByChainage: () => foldRevetAdjusts(revetShifts),
|
||||
linkFlagsByChainage: () => foldLinkFlags(linkDetached, followGrades),
|
||||
extraCountsByChainage: () => foldExtraCounts(extraCounts),
|
||||
extraSpansByChainage: () => foldExtraSpans(extraSpans),
|
||||
flushCulvertOptions: () => culvertOptions.flush(),
|
||||
queueCulvertOptions: (chainageM, patch) => culvertOptions.queue(chainageM, patch),
|
||||
load: () => {
|
||||
|
||||
Reference in New Issue
Block a user