refactor(472-3 B06 벽 · 기슭막이 · 배치): 구조물 기하 logic 분리 · 그림 파일은 그리기만
- logic 새 파일 다섯 — Cross_Wall_Geom(벽 1매) · Cross_Wall_Hatch_Geom(무늬 띠 · 물빼기 · 도수로 띠 · 원지반선) · Cross_Excavation_Geom(벽 터파기) · Cross_Design_Surface_Geom(암선 · 포장층) · Cross_Revetment_Geom(독립 기슭막이 배치) - logic 으로 옮김 — Body_Guard → Cross_Body_Guard · Structure_Layouts · Route_Carry_Patch(내용 그대로 · import 경로만) - inferStationInterval → common_util_station(글자표 없는 자리 · common_util_svg 는 다시 내보냄) — Node 묶음 ui_template_locale 끌림 끊음 - 부르는 쪽 import 줄 · 등록부 ts 경로 · 시험 · 도우미 경로 - test_472_3 GEOMETRY_PULLS 다섯 줄 걷음 · Wall_Hatch · Excavation · Design_Surface 세 줄은 Culvert · Box · Ford 그림 파일(518-2)이 그리기 함수로 부르는 동안 남김 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import type { PavementEntry } from "@util/common_util_structure_pavement";
|
||||
import type { CrossDesign } from "./B06_Section_Api_Fetch";
|
||||
import {
|
||||
pavementLayers,
|
||||
rockBoundarySegments,
|
||||
} from "./logic/B06_Section_Cross_Design_Surface_Geom";
|
||||
|
||||
const SVG_NS = "http://www.w3.org/2000/svg";
|
||||
|
||||
@@ -10,28 +14,17 @@ export function appendRockBoundaryOverlay(
|
||||
x: (offset: number) => number,
|
||||
y: (elevation: number) => number,
|
||||
): void {
|
||||
const segments: string[][] = [];
|
||||
let current: string[] = [];
|
||||
for (const sample of samples) {
|
||||
const elevation = sample.elevation_m;
|
||||
if (sample.valid === false || elevation === null || !Number.isFinite(elevation ?? NaN)) {
|
||||
if (current.length > 1) segments.push(current);
|
||||
current = [];
|
||||
continue;
|
||||
}
|
||||
current.push(`${x(sample.offset_m ?? 0)},${y((elevation as number) + offsetM)}`);
|
||||
}
|
||||
if (current.length > 1) segments.push(current);
|
||||
for (const points of segments) {
|
||||
for (const segment of rockBoundarySegments(samples, offsetM)) {
|
||||
const polyline = document.createElementNS(SVG_NS, "polyline");
|
||||
polyline.setAttribute("points", points.join(" "));
|
||||
polyline.setAttribute(
|
||||
"points",
|
||||
segment.map((p) => `${x(p.offset_m)},${y(p.elevation_m)}`).join(" "),
|
||||
);
|
||||
polyline.setAttribute("class", "b06-chart__rock-boundary");
|
||||
svg.append(polyline);
|
||||
}
|
||||
}
|
||||
|
||||
type Edge = { offset_m: number; elevation_m: number };
|
||||
|
||||
/** 포장사양 → 무늬(88) — 콘크리트 빗금 · 아스콘 점 · 쇄석 돌. 그 밖 = 채움만. */
|
||||
const PAVE_MARKS: Record<string, { size: number; marks: string }> = {
|
||||
콘크리트: { size: 6, marks: '<path d="M0,6 L6,0" class="b06-chart__pave-mark"/>' },
|
||||
@@ -49,21 +42,6 @@ const PAVE_MARKS: Record<string, { size: number; marks: string }> = {
|
||||
/** 무늬 id 는 문서 안에서 유일 — 카드 · 다시 그리기마다 새 번호(물넘이 빗금과 같은 방식). */
|
||||
let paveSeq = 0;
|
||||
|
||||
/** 확폭 끈 구간 — 규격 폭 끝(좌 = left − 확폭좌 · 우 = right + 확폭우 · 표고는 두 끝 사이 직선). */
|
||||
function standardEdges(edges: { left: Edge; right: Edge }, design: CrossDesign) {
|
||||
const { left, right } = edges;
|
||||
const span = right.offset_m - left.offset_m || 1;
|
||||
const at = (offset: number): Edge => ({
|
||||
offset_m: offset,
|
||||
elevation_m:
|
||||
left.elevation_m + ((right.elevation_m - left.elevation_m) * (offset - left.offset_m)) / span,
|
||||
});
|
||||
return {
|
||||
left: at(left.offset_m - (design.widening_left_m ?? 0)),
|
||||
right: at(right.offset_m + (design.widening_right_m ?? 0)),
|
||||
};
|
||||
}
|
||||
|
||||
type PaveMark = { type_id: string; start_m?: number | null; end_m?: number | null };
|
||||
|
||||
/** 포장층 범위 표식(종류 · 시작 · 끝)이 그 노면공인가 — 겹친 노면공 가름. */
|
||||
@@ -97,8 +75,8 @@ export function pavementAt<T extends PaveMark>(
|
||||
}
|
||||
|
||||
/**
|
||||
* 포장층 — 노면선(= 포장 윗면) 아래로 두께만큼. 노면공 범위(`section.pavement`)면 그 두께 · 무늬 ·
|
||||
* 확폭 켬/끔(여러 건은 아래로 차례로 쌓음) · 없으면 카드 포장 켬일 때 표준 두께 채움만.
|
||||
* 포장층 — 층 꼭짓점 = `pavementLayers`(두께 · 확폭 켬/끔 · 차례로 쌓음) · 여기는 무늬 · 범위 표식 ·
|
||||
* 그리기. 없으면 카드 포장 켬일 때 표준 두께 채움만.
|
||||
*/
|
||||
export function appendPavementOverlay(
|
||||
svg: SVGElement,
|
||||
@@ -107,20 +85,8 @@ export function appendPavementOverlay(
|
||||
y: (elevation: number) => number,
|
||||
pavement?: readonly PavementEntry[] | null,
|
||||
): void {
|
||||
const edges = design.carriageway_edges ?? design.road_edges;
|
||||
if (!edges) return;
|
||||
const layers = pavement?.length ? pavement : design.paved ? [null] : [];
|
||||
let depth = 0;
|
||||
for (const entry of layers) {
|
||||
const thickness = entry?.thickness_m ?? design.pavement_thickness_m ?? 0.2;
|
||||
const { left, right } = entry && !entry.widening_on ? standardEdges(edges, design) : edges;
|
||||
const points = [
|
||||
`${x(left.offset_m)},${y(left.elevation_m - depth)}`,
|
||||
`${x(right.offset_m)},${y(right.elevation_m - depth)}`,
|
||||
`${x(right.offset_m)},${y(right.elevation_m - depth - thickness)}`,
|
||||
`${x(left.offset_m)},${y(left.elevation_m - depth - thickness)}`,
|
||||
].join(" ");
|
||||
depth += thickness;
|
||||
for (const { entry, corners } of pavementLayers(design, pavement)) {
|
||||
const points = corners.map((p) => `${x(p.offset_m)},${y(p.elevation_m)}`).join(" ");
|
||||
const polygon = document.createElementNS(SVG_NS, "polygon");
|
||||
polygon.setAttribute("points", points);
|
||||
polygon.setAttribute("class", "b06-chart__pavement");
|
||||
|
||||
Reference in New Issue
Block a user