/* 구조물 폐회로 면적 — 벽이 성토 사면을 끊으면 면적이 그만큼 줄어드는지 확인. (2026-09-06 사용자 확정: 구조물 자체 면적을 빼는 게 아니라 그려지는 폐회로의 넓이다) TS 두 파일을 프로젝트 tsc 로 옮겨 실제 코드를 그대로 돌린다. */ import assert from "node:assert/strict"; import { execFileSync } from "node:child_process"; import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { pathToFileURL } from "node:url"; const out = mkdtempSync(join(tmpdir(), "aislo-areas-")); execFileSync( process.execPath, [ "./config/node_modules/typescript/bin/tsc", "common_util/common_util_cross_design_areas.ts", "common_util/common_util_cross_structure_areas.ts", "--outDir", out, "--module", "esnext", "--target", "es2022", "--moduleResolution", "bundler", "--ignoreConfig", ], { stdio: "inherit" }, ); // tsc 는 확장자 없는 상대 import 를 그대로 둔다 — node 가 읽게 `.js` 를 붙인다. const { readFileSync, writeFileSync } = await import("node:fs"); const target = join(out, "common_util_cross_structure_areas.js"); writeFileSync( target, readFileSync(target, "utf8").replace( /from "\.\/common_util_cross_design_areas"/, 'from "./common_util_cross_design_areas.js"', ), ); const { computeStructureAreas } = await import(pathToFileURL(target).href); // 평지 지반(표고 100). 설계선이 좌(−offset)로 갈수록 지반 아래로 파고든다 = 절토. const ground = []; const designLine = []; for (let o = -20; o <= 20; o += 1) { ground.push({ offset: o, elevation: 100 }); designLine.push({ offset_m: o, elevation_m: o >= 0 ? 100 : 100 + o * 0.5 }); } const wide = computeStructureAreas({ designLine, ground, trim: { minOffset: -20, maxOffset: 20 } }); const trimmed = computeStructureAreas({ designLine, ground, trim: { minOffset: -5, maxOffset: 20 } }); assert.ok(wide && trimmed, "면적 계산 결과가 나와야 한다"); // 전 구간: 0.5 * 20 * 10 = 100㎡ / 벽 안쪽만: 0.5 * 5 * 2.5 = 6.25㎡ assert.ok(Math.abs(wide.cutAreaM2 - 100) < 0.01, `전 구간 절토 100㎡ — 실제 ${wide.cutAreaM2}`); assert.ok(Math.abs(trimmed.cutAreaM2 - 6.25) < 0.01, `벽 안쪽 6.25㎡ — 실제 ${trimmed.cutAreaM2}`); // 벽 바깥을 성토부선이 대신 그리면 그만큼 다시 잡힌다(폐회로가 넓어진다). const withSlope = computeStructureAreas({ designLine, ground, trim: { minOffset: -5, maxOffset: 20, minSlope: { points: [{ offset: -10, elevation: 97.5 }, { offset: -5, elevation: 97.5 }] }, }, }); assert.ok(withSlope, "성토부선이 있는 경우도 계산돼야 한다"); assert.ok( withSlope.cutAreaM2 > trimmed.cutAreaM2, `구조물 선이 덮은 만큼 늘어야 한다: ${withSlope.cutAreaM2} > ${trimmed.cutAreaM2}`, ); console.log( `구조물 폐회로 면적 확인 — 전구간 ${wide.cutAreaM2.toFixed(2)}㎡ · 벽에서 끊음 ${trimmed.cutAreaM2.toFixed(2)}㎡ · 구조물선 포함 ${withSlope.cutAreaM2.toFixed(2)}㎡`, );