- 충돌 24 파일 = import 줄 다툼 — 518-2 새 경로(Cross_Culvert · Culvert_Geom · Extra · Wire · Types · Box_Geom · Ford_Geom · Ford_Pavement) + 518-3 새 경로(Cross_Body_Guard · Wall_Geom · Wall_Hatch_Geom · Excavation_Geom · Revetment_Geom · Structure_Layouts · Route_Carry_Patch)
- 518-2 logic 셋이 부르던 UI_Cross_Wall · Wall_Hatch · Body_Guard = 518-3 logic 경로로 · 518-3 새 logic 넷의 옛 Culvert_Types · Extra 경로 = 518-2 logic 으로
- test_472_3 GEOMETRY_PULLS 남은 3 줄(Design_Surface · Excavation · Wall_Hatch) 걷음 = 빈 목록
- Corridor_Structures prettier
- 확인 = 518-1 · 518-2 · 518-3 고친 시험 + golden_472 73 파일 444 통과 · typecheck 0 · design-calc · corridor 묶음 · 옛 판(1d5d63875) ↔ 합친 판 덧그림 대조 938 측점 같음
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
118 lines
4.7 KiB
TypeScript
118 lines
4.7 KiB
TypeScript
/* =============================================================================
|
|
* B06_Section_UI_Cross_Wall.ts
|
|
* 기슭막이 벽 **그리기**(기하 = `logic/B06_Section_Cross_Wall_Geom` · 472-3) — 배관 세트 벽
|
|
* (`_Cross_Culvert_Geom`/`_Culvert`)과 독립 기슭막이(`_Cross_Revetment`)가 같은 산식·같은 도형을 쓰도록 뽑아낸 층이다
|
|
* (2026-08-28 사용자: "배관용에서 배관만 빼면 대부분 동일해야"). 벽 1매의 합성 단면
|
|
* (하부 사다리꼴 + 상부 평행사변형, 배면 수직·전면 1:0.3)과 그 돌쌓기 표현은 여기 하나뿐.
|
|
*
|
|
* 관 유입·유출 흙막이 · 추가 흙막이 · 사면안정 흙막이 · 옹벽이 모두 이 함수 하나로 선다.
|
|
* 형태가 바꾸는 것은 안 무늬(`_Cross_Wall_Hatch`)뿐 — 외곽은 높이·자리·기울기로만 정함.
|
|
* ========================================================================== */
|
|
|
|
import type { OffsetPoint, WallLayout } from "./logic/B06_Section_Cross_Culvert_Types";
|
|
import { appendWallHatch } from "./B06_Section_UI_Cross_Wall_Hatch";
|
|
|
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
|
|
function polygon(
|
|
points: Array<[number, number]>,
|
|
className: string,
|
|
tooltip: string,
|
|
): SVGPolygonElement {
|
|
const shape = document.createElementNS(SVG_NS, "polygon");
|
|
shape.setAttribute("points", points.map(([px, py]) => `${px},${py}`).join(" "));
|
|
shape.setAttribute("class", className);
|
|
if (tooltip) {
|
|
const title = document.createElementNS(SVG_NS, "title");
|
|
title.textContent = tooltip;
|
|
shape.append(title);
|
|
}
|
|
return shape;
|
|
}
|
|
|
|
/**
|
|
* 벽 1매를 SVG로 그린다 — 폴리곤 + 대각 이음선 + 계류측 기운 띠의 돌쌓기 해칭.
|
|
* 배관 오버레이(`_Cross_Culvert` 161~246행)와 **같은 그리기**. 선택·강조 배선은 호출자
|
|
* 몫이라 여기서는 본체 폴리곤만 돌려준다. `keyId`는 clipPath id 중복 방지용.
|
|
*/
|
|
export function drawRevetWall(
|
|
layer: SVGElement,
|
|
wall: WallLayout,
|
|
x: (offset: number) => number,
|
|
toDisplayY: (elevation: number) => number,
|
|
className: string,
|
|
tooltip: string,
|
|
keyId: string,
|
|
): SVGPolygonElement {
|
|
const revetShape = polygon(
|
|
wall.points.map((p) => [x(p.offset), toDisplayY(p.elevation)] as [number, number]),
|
|
className,
|
|
tooltip,
|
|
);
|
|
layer.append(revetShape);
|
|
|
|
// 이음선 + **형태별 표현**(돌/콘크리트/돌망태/통나무/바자)은 공용 해칭이 맡는다
|
|
// (2026-08-30 사용자 지시 3) — 배관 오버레이와 같은 함수를 쓴다.
|
|
appendWallHatch(layer, wall, x, toDisplayY, keyId);
|
|
return revetShape;
|
|
}
|
|
|
|
/** 성토·절토 접속선(공사 계획선) 폴리라인 — 설계선과 같은 보라 실선. */
|
|
export function appendPlanLine(
|
|
layer: SVGElement,
|
|
points: OffsetPoint[],
|
|
x: (offset: number) => number,
|
|
toDisplayY: (elevation: number) => number,
|
|
tooltip: string,
|
|
className = "b06-chart__design-cross",
|
|
): void {
|
|
if (points.length < 2) return;
|
|
const line = document.createElementNS(SVG_NS, "polyline");
|
|
line.setAttribute(
|
|
"points",
|
|
points.map((p) => `${x(p.offset)},${toDisplayY(p.elevation)}`).join(" "),
|
|
);
|
|
line.setAttribute("class", className);
|
|
if (tooltip) {
|
|
const title = document.createElementNS(SVG_NS, "title");
|
|
title.textContent = tooltip;
|
|
line.append(title);
|
|
}
|
|
layer.append(line);
|
|
}
|
|
|
|
/**
|
|
* 벽 안으로 지나가는 다른 선(원지반 · 설계선 · 비탈 · 다른 외곽)을 가린다(66-5) — 흙막이 · 옹벽을
|
|
* 바탕색 덮개와 함께 맨 위로 올림. 벽 자기 외곽 · 무늬는 그대로. 관 · 클릭 판정면 · 글은 그 위로
|
|
* 다시 올려 지금 차례(관이 벽을 지나감 · 판정면 맨 위)를 지킨다.
|
|
*/
|
|
export function raiseWalls(layer: SVGElement): void {
|
|
const kids = [...layer.children];
|
|
const groups = kids
|
|
.filter((el) => el.classList.contains("b06-chart__culvert-revet"))
|
|
.map((wall) => {
|
|
// 무늬 = 벽 바로 뒤의 clipPath + 잘린 묶음(`appendWallHatch`)
|
|
const hatch: Element[] = [];
|
|
let next = wall.nextElementSibling;
|
|
while (
|
|
next &&
|
|
(next.tagName === "clipPath" ||
|
|
next.getAttribute("clip-path")?.startsWith("url(#b06-revet-clip-"))
|
|
) {
|
|
hatch.push(next);
|
|
next = next.nextElementSibling;
|
|
}
|
|
const cover = document.createElementNS(SVG_NS, "polygon");
|
|
cover.setAttribute("points", wall.getAttribute("points") ?? "");
|
|
cover.setAttribute("class", "b06-chart__wall-cover");
|
|
return [cover, wall, ...hatch];
|
|
});
|
|
if (!groups.length) return;
|
|
for (const group of groups) layer.append(...group);
|
|
layer.append(
|
|
...kids.filter((el) =>
|
|
el.matches(".b06-chart__culvert-pipe, .b06-chart__culvert-revet-hit, text"),
|
|
),
|
|
);
|
|
}
|