Files
Aislo/B05_Profile/B05_Profile_UI_RouteEdit_Cross_Card.ts
T

132 lines
4.8 KiB
TypeScript

/* =============================================================================
* B05_Profile_UI_RouteEdit_Cross_Card.ts
* 평면 「횡단」 · 「이전 횡단」 판 그림 = **B06 횡단 카드 읽기 전용**(393-2) — 구조물 · 포장 · 면적 · 축 ·
* 종단 계획고 · 횡단 설계가 B06 카드와 같은 그림.
*
* · 자료 = 새 노선 상세(계산 묶음) · 없으면 받아 둔 저장 상세 · 노선 초안 중 새 상세가 아직 없으면 없음
* (판은 옛 선 그림 `_Cross_Draw` 로 · 종단 임시 횡단 창도 그것 그대로)
* · 단면 사본(station_id 앞머리 · design 사본) — B06 고름 · 줌 기억 · 면적 원본을 안 건드림
* · 구조물 자리 = 정본만 읽는 제어기(`Structure_Layouts` · 세월교 · 박스 조정값) · 누름 막음(줌 단추만)
* ========================================================================== */
import "../B06_Section/B06_Section_UI_Style_Cross_Controls.css";
import { pipelineDetail } from "../A00_Common/design/design_pipeline_page";
import type { DesignPipeline } from "../A00_Common/design/logic/design_pipeline";
import { nearestWithin } from "../A00_Common/design/design_selection";
import type { CrossSection } from "../B06_Section/B06_Section_Api_Fetch";
import { peekSectionDetail } from "../B06_Section/B06_Section_Section_Store";
import {
extraWalls,
inletStructure,
revetOffset,
} from "../B06_Section/B06_Section_Structure_Layouts";
import { DEFAULT_BOX_SIDE_ADJUST } from "../B06_Section/B06_Section_UI_Cross_Box_Geom";
import type { BoxControl } from "../B06_Section/B06_Section_UI_Cross_Box_Panel";
import { culvertLinkFor, type CulvertLink } from "../B06_Section/B06_Section_UI_Cross_Culvert_Wire";
import { fordAdjustOf } from "../B06_Section/B06_Section_UI_Cross_Ford_Geom";
import type { FordControl } from "../B06_Section/B06_Section_UI_Cross_Ford_Panel";
import { createCrossSectionCard } from "../B06_Section/B06_Section_UI_Cross_View";
import { designElevationAt } from "../B06_Section/B06_Section_UI_Section_Common";
/** 판 하나가 그릴 측점 — 그때 사본(이전 판으로 내려도 그대로). */
export interface RouteCrossSource {
section: CrossSection;
designZ: number | undefined;
link: CulvertLink | undefined;
}
const none = (): void => undefined;
/** 그 측점 단면 사본 — 상세가 없거나(초안 중 새 상세 전) 측점이 없으면 null. */
export function routeCrossSource(
projectId: string,
pipe: DesignPipeline | null,
chainageM: number,
pane: string,
): RouteCrossSource | null {
const detail =
pipelineDetail(projectId) ?? (pipe?.input("route") ? null : peekSectionDetail(projectId));
const sections = detail?.cross_sections ?? [];
const found = nearestWithin(sections, chainageM, (entry) => entry.chainage_m);
if (!detail || !found) return null;
const profiles = detail.longitudinal.design_profiles;
const planZ = designElevationAt(profiles, found.chainage_m);
return {
section: {
...found,
station_id: `b05-${pane}-${found.station_id}`,
design: found.design && { ...found.design },
},
designZ: planZ === undefined ? undefined : planZ - (found.design?.surface_drop_m ?? 0),
link: found.culvert
? undefined
: culvertLinkFor(found, sections, (at) => designElevationAt(profiles, at) ?? null),
};
}
/** B06 횡단 카드 읽기 전용 — 판 폭 · 그림 높이(px)로. */
export function routeCrossCard(
source: RouteCrossSource,
intervalM: number,
halfWidthM: number | undefined,
widthPx: number,
plotHeightPx: number,
): HTMLElement {
const { section } = source;
const design = section.design;
const ford: FordControl = {
adjustFor: () => fordAdjustOf(design?.ford_adjust),
update: none,
reset: none,
setPipe: none,
setWing: none,
selectedFor: () => null,
select: none,
};
const box: BoxControl = {
adjustFor: () => ({
left: { ...DEFAULT_BOX_SIDE_ADJUST, ...(design?.box_adjust?.left ?? {}) },
right: { ...DEFAULT_BOX_SIDE_ADJUST, ...(design?.box_adjust?.right ?? {}) },
}),
update: none,
reset: none,
setBody: none,
setWing: none,
selectedFor: () => null,
select: none,
};
const card = createCrossSectionCard(
section,
false,
1,
none,
intervalM,
halfWidthM,
widthPx,
plotHeightPx,
source.designZ,
undefined,
undefined,
null,
undefined,
undefined,
revetOffset,
inletStructure,
extraWalls,
source.link,
undefined,
undefined,
ford,
box,
);
// 읽기 전용 — 벽 · 선 · 면적 고름을 막음(줌 단추만 통과)
card.addEventListener(
"click",
(event) => {
if (!(event.target as Element).closest("button")) event.stopPropagation();
},
true,
);
return card;
}