feat(365-5): 초안 소단 고침 → 묶음 cross 입력
- 초안 cross 소단 = 지금 구조물(따라간 자리)의 소단 구간(bermAt · crossWithBerm) · 쪽 깊이 = 세션 bermdepth(측점 열쇠) — 노선 초안 동안 소단 고침도 카드에 - 저장 노선은 지금처럼 다시 셈 창구(세션 사본) · 노선 밖 고침은 그대로 - 시험 test_365(구간 안 소단 · 밖 없음 · 깊이 고침 1바퀴) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TteK8mfYZetk5P3bEZkyVZ
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
* 암 경계 · 암 경사 · 소단) + 얹힌 시설 맥락(포장 · 물넘이 기울임 · 세월교 노면 하강). 단면 유형 · 측구
|
||||
* 방향은 새 지형이 정함(`logic/B05_Profile_Pipeline_Detail.ts` `crossWithUphill`) · 노견 확장 · 소단
|
||||
* 깊이는 안 넘김. 값 = 상세에 얹힌 설계 위에 세션 고침(측점 열쇠 칸 · 지반 유형 · 측구 · 2단 경사 · 암 경계 ·
|
||||
* 암 경사) — 노선 초안 동안 B06 고침은 저장 상세에 안 얹혀도 입력에 들어감(365-2). 부를 때마다 모음.
|
||||
* 암 경사 · 소단 깊이) — 노선 초안 동안 B06 고침은 저장 상세에 안 얹혀도 입력에 들어감(365-2 · 365-5). 부를 때마다 모음.
|
||||
* ========================================================================== */
|
||||
|
||||
import { readState } from "../b_page_state";
|
||||
@@ -75,7 +75,7 @@ function carried(section: CrossSection): Record<string, unknown> {
|
||||
|
||||
/** 세션 칸 하나를 측점 열쇠마다 — 옛 열쇠(누가거리 · `at:`)는 읽는 쪽이 옮긴 뒤에 들어옴(빼고 봄). */
|
||||
function sessionCells(
|
||||
name: "crossdesign" | "rockb" | "cutslope",
|
||||
name: "crossdesign" | "rockb" | "cutslope" | "bermdepth",
|
||||
projectId: string,
|
||||
routeId: number,
|
||||
): Array<[string, unknown]> {
|
||||
@@ -102,6 +102,12 @@ function sessionCarried(projectId: string, routeId: number): CrossInput["byKey"]
|
||||
const ratio = finite(value);
|
||||
if (ratio !== null) (out[key] ??= {}).cutSlopeRatio = ratio > 0 ? ratio : null;
|
||||
}
|
||||
// 소단 쪽 깊이(194-1) — 소단 제원은 구조물 구간이 정함(`crossWithBerm` · 365-5)
|
||||
for (const [key, value] of sessionCells("bermdepth", projectId, routeId)) {
|
||||
const sides = (value ?? {}) as Record<string, unknown>;
|
||||
if (finite(sides.left) !== null) (out[key] ??= {}).bermDepthLeftM = sides.left;
|
||||
if (finite(sides.right) !== null) (out[key] ??= {}).bermDepthRightM = sides.right;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
* (`pipelineGrade` · 노선 초안 동안은 alignment-draft 노선 `DRAFT_ROUTE_ID`) · 횡단 = 저장 상세의 측점
|
||||
* 입력 + 세션 고침(`design_pipeline_cross.ts` · 부를 때마다 모음 · 횡단 고침 뒤 `pipelineCross` · 365-2) ·
|
||||
* 관 = 가게 초안 → 저장 관 목록(좌표 · id) · 구조물 = 가게 초안 → 저장분.
|
||||
* 고리(365-2) — 열 때 · 페이지 들어올 때(`reconcilePagePipeline`) 입력(세션 · 가게)을 묶음이 쥔 입력과 견줌 →
|
||||
* 다르면 한 바퀴 → 끝난 뒤 다시 견줌 · 최대 `RECONCILE_ROUNDS` · 넘으면 `onUnstable`(「계산 불안정」 한 줄).
|
||||
* 고리(365-2) — 열 때 · 들어올 때 입력 대 묶음 입력 · 다르면 한 바퀴 · 최대 3 · 넘으면 `onUnstable`.
|
||||
* 출력 — 가게 stations · profile · footprint · generation · 노선 초안이 있으면 종단도가 새 첫 계획선 ·
|
||||
* 옮긴 계획고 · 새 노선 상세(`pipelineDetail` — 지반 · 측점 · 횡단 면적 → 유토곡선)를 그림.
|
||||
* 첫 계산 = 열 때 한 번(저장 노선 · 발자국 · 저장 안 한 노선 초안이 있으면 그 노선).
|
||||
@@ -87,8 +86,10 @@ import {
|
||||
routeRange,
|
||||
} from "../../B05_Profile/logic/B05_Profile_Pipeline_Grade";
|
||||
import {
|
||||
crossWithBerm,
|
||||
crossWithUphill,
|
||||
draftSectionDetail,
|
||||
type BermAt,
|
||||
type CrossInput,
|
||||
} from "../../B05_Profile/logic/B05_Profile_Pipeline_Detail";
|
||||
import { buildStations } from "../../B05_Profile/logic/B05_Profile_Sections_Stations";
|
||||
@@ -148,12 +149,13 @@ export interface PagePipelineOptions {
|
||||
) => (stations: PipelineStation[]) => Promise<string>;
|
||||
/** 고리가 `RECONCILE_ROUNDS` 바퀴 안에 안 맞음 — 「계산 불안정」 한 줄(365-2). */
|
||||
onUnstable?: () => void;
|
||||
/** 저장 노선 cross = 다시 셈 창구 한 벌(365-4) — 상세 설계를 고치고 그 값을 냄 · 측점이 상세와 다르면 null
|
||||
* (묶음 엔진). 주면 종단도가 계획고 편집 뒤 따로 다시 셈 안 함(`pipelineOwnsCross`). */
|
||||
/** 소단 구간(지금 구조물 목록 → 누가거리마다 제원) — 초안 cross 가 따라간 구조물로 소단을 셈(365-5). */
|
||||
bermAt?: (structures: unknown) => BermAt;
|
||||
/** 저장 노선 cross = 다시 셈 창구 한 벌(365-4 · 측점이 상세와 다르면 null = 엔진) · 주면 종단도는 따로 안 셈. */
|
||||
savedCross?: (
|
||||
detail: SectionDetailResponse,
|
||||
d: SectionDetailResponse,
|
||||
routeId: number,
|
||||
stations: ReadonlyArray<PipelineStation>,
|
||||
s: PipelineStation[],
|
||||
) => Promise<CrossOutput | null>;
|
||||
}
|
||||
|
||||
@@ -362,26 +364,27 @@ function createPagePipeline(
|
||||
ground: createGroundStage(groundDeps),
|
||||
planline: createPlanlineStage({ savedBase: () => savedSource().base, savedLine }),
|
||||
profile: profileStage,
|
||||
// 단면 유형 기본값 = 새 지형 상단측(서버 노선 저장 규칙) — 단계 본문은 그대로 부름 · 저장 노선 = 다시 셈
|
||||
// 창구 한 벌(카드 · 유토곡선이 보는 상세 설계 · 365-4)
|
||||
// 단면 유형 = 새 지형 상단측 · 소단 = 지금 구조물(365-5) · 저장 노선 = 다시 셈 창구 한 벌(365-4) · 엔진은
|
||||
// 창구 출력을 앞 결과로 안 이어 씀(초안 = 새로고침)
|
||||
cross: (ctx) => {
|
||||
// 엔진은 다시 셈 창구가 낸 앞 출력을 이어 쓰지 않음 — 초안 = 새로고침과 같은 값(365-4)
|
||||
const stations = ctx.out.ground?.stations ?? [];
|
||||
const engine = () =>
|
||||
crossStage.stage({
|
||||
...ctx,
|
||||
prev: ctx.prev && savedOut.has(ctx.prev) ? null : ctx.prev,
|
||||
inputs: {
|
||||
...ctx.inputs,
|
||||
cross: crossWithUphill(
|
||||
ctx.inputs.cross as CrossInput | null,
|
||||
ctx.out.ground?.stations ?? [],
|
||||
cross: crossWithBerm(
|
||||
crossWithUphill(ctx.inputs.cross as CrossInput | null, stations),
|
||||
stations,
|
||||
options.bermAt?.(ctx.inputs.structures) ?? null,
|
||||
),
|
||||
},
|
||||
});
|
||||
const { detail = null, routeId } = savedSource();
|
||||
const saved =
|
||||
!ctx.inputs.route && detail && typeof routeId === "number"
|
||||
? options.savedCross?.(detail, routeId, ctx.out.ground?.stations ?? [])
|
||||
? options.savedCross?.(detail, routeId, stations)
|
||||
: null;
|
||||
if (!saved) return engine();
|
||||
return saved.then((out) => {
|
||||
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
swapSectionStations,
|
||||
} from "../../B06_Section/B06_Section_Section_Store";
|
||||
import { refreshCrossDesigns } from "../../B06_Section/B06_Section_Cross_Refresh";
|
||||
import { bermSpansFromStructures, bermSpecAt } from "../../B06_Section/B06_Section_UI_Page_Persist";
|
||||
import { detailCross } from "../../B05_Profile/logic/B05_Profile_Pipeline_Detail";
|
||||
|
||||
function L(key: keyof typeof ui_locales): string {
|
||||
@@ -212,6 +213,11 @@ function startPagePipeline(shared: DesignPageShared, profile: DesignProfile): vo
|
||||
onCorridorStale: () => each((hooks) => hooks.onCorridorStale?.()),
|
||||
onFacilitiesFollowed: (far) => each((hooks) => hooks.onFacilitiesFollowed?.(far)),
|
||||
onUnstable: () => showToast(L("Design_Pipeline_Unstable"), "warning"),
|
||||
// 초안 소단 = 지금 구조물(따라간 자리)의 소단 구간(365-5 · 저장 노선은 다시 셈 창구가 세션 사본으로)
|
||||
bermAt: (structures) => {
|
||||
const spans = bermSpansFromStructures(Array.isArray(structures) ? structures : []);
|
||||
return (chainageM) => bermSpecAt(spans, chainageM);
|
||||
},
|
||||
// 저장 노선 횡단 = 다시 셈 창구 한 벌(365-4) — 카드 · 유토곡선 · [저장] 패치가 보는 상세 설계를 고치고 그 값을
|
||||
// 묶음 출력으로(발자국 · 평면 횡단 판) · 측점이 상세와 다르면(갈아끼움 전) 묶음 엔진
|
||||
savedCross: async (detail, routeId, stations) => {
|
||||
|
||||
Reference in New Issue
Block a user