- 카드 고름 = 서버 이은 누가(저장 갈래) 위에 캐시 고름 - 지점 누름(손 떨림 안)은 끌기 아님 · 집은 자리 차 지킴 - 횡단 판 B05 RouteEdit 꾸밈 css · 끌기 끝나면 옛 횡단 비움 - 진행 요청 실패 = 알림 뒤 화면 되돌림(서버 일은 그대로) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
91 lines
3.3 KiB
TypeScript
91 lines
3.3 KiB
TypeScript
/* =============================================================================
|
|
* D03_PlanAnalysis_UI_Cross.ts
|
|
* D03 하 패널 — 누른 측점의 지반선 횡단(PLAN 530-3). 계산 = 화면 TS 즉시(① 짝 `sectionsGround` ↔
|
|
* `generate_sections` · 격자 = 그 연도 DEM 평활본) · 그림 = B05 `buildCrossSvg` 지반만.
|
|
* ========================================================================== */
|
|
|
|
import "../B05_Profile/B05_Profile_UI_Style_RouteEdit.css";
|
|
import { createWorkflowPanelHandle } from "@ui/ui_template_overlay";
|
|
import { stationLabel } from "../common_util/common_util_station";
|
|
import type { DtmGrid } from "../common_util/common_util_surface_sampler";
|
|
import { buildCrossSvg } from "../B05_Profile/B05_Profile_UI_RouteEdit_Cross_Draw";
|
|
import {
|
|
sectionsGround,
|
|
type StationGround,
|
|
} from "../B05_Profile/logic/B05_Profile_Sections_Ground";
|
|
import type { Vertex } from "./logic/D03_PlanAnalysis_Plan";
|
|
import { PLAN_STATION_INTERVAL_M } from "./D03_PlanAnalysis_UI_Map";
|
|
|
|
export interface PlanCross {
|
|
root: HTMLElement;
|
|
/** `chainage` = 등록 누가 · `localM` = 그 연도 노선 위 누가 · 돌려줌 = 그린 측점 지반(못 읽으면 null). */
|
|
show: (
|
|
chainage: number,
|
|
year: number,
|
|
line: Vertex[],
|
|
localM: number,
|
|
grid: DtmGrid,
|
|
) => StationGround | null;
|
|
clear: (text: string) => void;
|
|
}
|
|
|
|
export function createPlanCross(): PlanCross {
|
|
const root = document.createElement("section");
|
|
root.className = "d03-plan__cross";
|
|
const handle = createWorkflowPanelHandle("bottom", "down", "횡단");
|
|
const head = document.createElement("div");
|
|
head.className = "d03-plan__cross-head";
|
|
const body = document.createElement("div");
|
|
body.className = "d03-plan__cross-body";
|
|
root.append(handle.root, head, body);
|
|
let open = true;
|
|
handle.setOpen(open);
|
|
handle.root.addEventListener("click", () => {
|
|
open = !open;
|
|
root.classList.toggle("is-collapsed", !open);
|
|
handle.setOpen(open);
|
|
});
|
|
|
|
const clear = (text: string): void => {
|
|
head.textContent = "";
|
|
body.replaceChildren(Object.assign(document.createElement("p"), { textContent: text }));
|
|
delete root.dataset.chainage;
|
|
};
|
|
clear("평면에서 측점을 누르면 그 자리 지반선 횡단이 보입니다.");
|
|
|
|
return {
|
|
root,
|
|
clear,
|
|
show(chainage, year, line, localM, grid) {
|
|
const station = sectionsGround(line, [localM], grid).stations[0];
|
|
if (!station) {
|
|
clear("이 측점의 지반을 읽지 못했습니다.");
|
|
return null;
|
|
}
|
|
const name = stationLabel(chainage, PLAN_STATION_INTERVAL_M, 1);
|
|
const z = station.center_z === null ? "—" : `${station.center_z.toFixed(2)} m`;
|
|
head.textContent = `${year}년 · ${name} · 중심 지반고 ${z}`;
|
|
root.dataset.chainage = String(chainage);
|
|
const rect = body.getBoundingClientRect();
|
|
const plot = buildCrossSvg(
|
|
{
|
|
status: "success",
|
|
chainage_m: chainage,
|
|
label: name,
|
|
uphill_side: station.uphill_side,
|
|
plan_radius_m: null,
|
|
curve_widening_m: null,
|
|
cross_half_width_m: 20,
|
|
samples: station.samples,
|
|
design: null,
|
|
},
|
|
Math.max(rect.width, 320),
|
|
Math.max(rect.height, 160),
|
|
true,
|
|
);
|
|
body.replaceChildren(plot.svg);
|
|
return station;
|
|
},
|
|
};
|
|
}
|