Merge remote-tracking branch 'origin/sub_laptop_7' into main_laptop_1
This commit is contained in:
@@ -43,6 +43,7 @@ import {
|
||||
markAlignmentSaved,
|
||||
readAlignmentDraft,
|
||||
} from "../../B05_Profile/B05_Profile_UI_Profile_Edit";
|
||||
import { readAlignment } from "../../B05_Profile/logic/B05_Profile_UI_Profile_Data";
|
||||
import {
|
||||
analysisTerrain,
|
||||
fetchRoutePlan,
|
||||
@@ -141,7 +142,7 @@ export function routeDraftBridge(
|
||||
export const pipelineGrade = (projectId: string, edits: AlignmentEdits): void =>
|
||||
pages.get(projectId)?.grade(edits);
|
||||
|
||||
/** 저장 종단 기준이 바뀜(새 상세 · 구조물 측점) — 처음부터 다시. */
|
||||
/** 저장 정본이 바뀜(새로 받은 상세 · 새 노선) — 처음부터 다시. 갈아끼운 상세 · 같은 상세 다시 그림은 안 셈. */
|
||||
export const restartPagePipeline = (projectId: string): void => pages.get(projectId)?.restart();
|
||||
|
||||
/** 유토곡선 설정(토량환산계수 · 자연방토 경사) — masshaul 단계 재료 · 표준단면이 막 왔으면 횡단 입력도. */
|
||||
@@ -178,19 +179,43 @@ function createPagePipeline(
|
||||
let savedStations: PipelineStation[] = [];
|
||||
let crossSource: { detail: SectionDetailResponse; source: PipelineCrossSource | null } | null =
|
||||
null;
|
||||
/** 저장 정본(서버가 준 상세 · 노선 번호) — 측점 갈아끼움(swap)이 만든 새 상세는 지반 표본 배열을
|
||||
* 그대로 둠 → 정본 아님(묶음 출력 → 상세 → 다시 묶음 고리를 끊음). */
|
||||
let canon: { routeId: unknown; samples: unknown; detail: SectionDetailResponse | null } | null =
|
||||
null;
|
||||
let shown: SectionDetailResponse | null = null;
|
||||
let ready = false;
|
||||
let started = false;
|
||||
/** 앞 종단이 노선 초안으로 셈한 것인가 — 초안을 버리면 저장 기준으로 다시 그림. */
|
||||
let drawnDraft = false;
|
||||
let disposed = false;
|
||||
/** 열 때 · 정본이 바뀐 차례(start) 번호 — 측점 · 종단을 가게에 안 냄(상세 = 저장 정본 그대로). */
|
||||
let openGeneration = -1;
|
||||
|
||||
const savedLine = (): Vertex[] | null =>
|
||||
plan ? plan.planned.map(([x, y]): Vertex => [x, y]) : null;
|
||||
const savedCurves = () =>
|
||||
(plan?.curves ?? []).map(({ start, apex, end, radius_m }) => ({ start, apex, end, radius_m }));
|
||||
/** 저장 정본이 바뀌었나(새로 받은 상세 · 새 노선) — 바뀌었으면 잡아 둠. */
|
||||
const canonChanged = (): boolean => {
|
||||
const { detail = null, routeId } = link.pipelineSource();
|
||||
const samples = detail?.longitudinal.samples;
|
||||
if (canon && canon.routeId === routeId && canon.samples === samples) return false;
|
||||
canon = { routeId, samples, detail };
|
||||
return true;
|
||||
};
|
||||
/** 저장 노선 계획고 편집(세션 초안 → 저장분) — 노선 초안을 버리면 이것으로 돌아옴. */
|
||||
const savedEdits = (): AlignmentEdits => {
|
||||
const routeId = canon?.routeId;
|
||||
const longitudinal = canon?.detail?.longitudinal;
|
||||
return (
|
||||
(typeof routeId === "number" ? readAlignmentDraft(routeId) : null) ??
|
||||
(longitudinal && readAlignment(longitudinal)?.edits) ??
|
||||
emptyEdits()
|
||||
);
|
||||
};
|
||||
const crossNow = (): PipelineCrossSource | null => {
|
||||
const detail = link.pipelineSource().detail ?? null;
|
||||
const detail = canon?.detail ?? null;
|
||||
if (!detail) return null;
|
||||
if (crossSource?.detail !== detail || !crossSource.source)
|
||||
crossSource = { detail, source: pipelineCrossSource(projectId, detail, savedStations) };
|
||||
@@ -204,7 +229,14 @@ function createPagePipeline(
|
||||
minRadiusM: () => plan?.min_radius_m ?? 0,
|
||||
savedLine: () => plan && { line: savedLine()!, curves: savedCurves() },
|
||||
}),
|
||||
follow: createFollowStage({ savedLine }),
|
||||
follow: createFollowStage({
|
||||
savedLine,
|
||||
saved: () => ({
|
||||
pipes: store.get("pipes") ?? savedPipes,
|
||||
structures: store.get("structures") ?? savedStructures,
|
||||
alignment: savedEdits(),
|
||||
}),
|
||||
}),
|
||||
stations: createStationsStage({ intervalM: options.stationIntervalM, types: () => types }),
|
||||
ground: createGroundStage(groundStageDeps(projectId)),
|
||||
planline: createPlanlineStage({ savedBase: () => link.pipelineSource().base, savedLine }),
|
||||
@@ -231,7 +263,11 @@ function createPagePipeline(
|
||||
},
|
||||
},
|
||||
});
|
||||
pipe.subscribe(publishToStore(store));
|
||||
const publish = publishToStore(store);
|
||||
pipe.subscribe((event) => {
|
||||
const saved = event.kind === "stage" && (event.stage === "ground" || event.stage === "profile");
|
||||
if (!(saved && event.generation === openGeneration)) publish(event);
|
||||
});
|
||||
pipe.subscribe((event) => {
|
||||
if (event.kind !== "stage" || (event.stage !== "profile" && event.stage !== "cross")) return;
|
||||
const draft = pipe.input("route") !== null;
|
||||
@@ -270,8 +306,10 @@ function createPagePipeline(
|
||||
};
|
||||
const start = (): void => {
|
||||
if (disposed || !ready || !link.pipelineSource().base) return;
|
||||
canonChanged();
|
||||
started = true;
|
||||
void pipe.start(inputsNow());
|
||||
openGeneration = pipe.generation;
|
||||
};
|
||||
|
||||
/** 저장 노선(그린 선 · 곡선표 · 기본 반경) · 그 측점 열쇠 — [저장] 뒤 다시 받음(`restart`). */
|
||||
@@ -343,7 +381,7 @@ function createPagePipeline(
|
||||
},
|
||||
restart() {
|
||||
if (!started) return start();
|
||||
void loadPlan().then(start);
|
||||
if (canonChanged()) void loadPlan().then(start); // 갈아끼움 · 같은 상세 다시 그림은 안 셈
|
||||
},
|
||||
earthwork(context) {
|
||||
earthwork = context;
|
||||
|
||||
@@ -494,13 +494,13 @@ export function createDesignProfile(ctx: DesignProfileContext) {
|
||||
const routeChanged = nextRouteId !== routeId;
|
||||
const carried = routeChanged && store.edited() ? store.edits() : null;
|
||||
// 서버 저장분을 기준으로 삼되, 남아 있는 세션 초안이 있으면 그쪽을 우선한다.
|
||||
if (routeChanged || !store.dirty()) {
|
||||
if (routeChanged || (store !== preview && !store.dirty())) {
|
||||
routeId = nextRouteId ?? routeId;
|
||||
savedEdits = stored?.edits ?? emptyEdits();
|
||||
store = createProfileEditStore(routeId, savedEdits, () => rebuild());
|
||||
}
|
||||
storedBase = stored ? toAlignmentBase(stored) : null;
|
||||
base = listed();
|
||||
if (store !== preview) base = listed(); // 노선 초안 그림은 그대로(갈아끼운 상세)
|
||||
// 이월분은 base 설정 후 미저장 초안으로 커밋한다(확정 시 전송·재탐색 후 새로고침에도 유지).
|
||||
if (carried) store.replace(carried);
|
||||
alignment = base ? buildAlignment(base, store.edits()) : null;
|
||||
@@ -580,7 +580,7 @@ export function createDesignProfile(ctx: DesignProfileContext) {
|
||||
/** 비정규 측점 목록을 반영해 그래프(세로선+라벨)·테이블(주석)을 다시 그린다. */
|
||||
setIrregularStations(stations: IrregularStation[]) {
|
||||
irregularStations = stations;
|
||||
base = listed();
|
||||
if (store !== preview) base = listed();
|
||||
if (base) alignment = buildAlignment(base, store.edits());
|
||||
pagePipeline.restartPagePipeline(projectId);
|
||||
draw();
|
||||
|
||||
Reference in New Issue
Block a user