feat(D03): 예상 횡단 순수 함수 — 표준 횡단 기본값 · 계획고 = 중심 지반고 · 미교차 넓힘 · 코리도 측점 꼴(PLAN 544-1)
- 새 logic/D03_PlanAnalysis_Expect.ts — 공용 computeCrossDesign + B 초기 기본(리핑암 · 산쪽 절토 · 일반 측구 · 암 경계 기본) · extendUnclosed - 새 시험 test_544_1_plan_expect.py — TS 설계선 · 절 · 성토 ㎡ = 파이썬 compute_cross_design Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
/* =============================================================================
|
||||
* D03_PlanAnalysis_Expect.ts
|
||||
* D03 예상 횡단(PLAN 544-1 · 요구 363-1) — 측점 지반 → 표준 횡단 기본값 설계선 · 절 · 성토 ㎡.
|
||||
* 셈 = 공용 `computeCrossDesign`(① 짝 `compute_cross_design` · 거울 `test_b06_cross_design_mirror.py`)
|
||||
* · 기본 = B 초기 설계와 같음(리핑암 · 산쪽 절토 · 일반 측구 · 암 경계 = 서버 기본) · 계획고 = 측점 중심 지반고
|
||||
* · 미교차 = `extendUnclosed`(격자 있을 때) · 곡선 확폭 없음 · 보기만(저장 없음).
|
||||
* 3D = 같은 단면을 B05 `buildCorridor` 가 읽는 측점 꼴로(`expectSections`).
|
||||
* 시험 `resources/tester/test_544_1_plan_expect.py`.
|
||||
* ========================================================================== */
|
||||
|
||||
import {
|
||||
computeCrossDesign,
|
||||
type CrossDesignOptions,
|
||||
type CrossDesignResult,
|
||||
type StandardCrossSectionSpec,
|
||||
} from "../../common_util/common_util_cross_design";
|
||||
import type { DtmGrid } from "../../common_util/common_util_surface_sampler";
|
||||
import {
|
||||
extendUnclosed,
|
||||
type CrossGroundPoint,
|
||||
type StationGround,
|
||||
} from "../../B05_Profile/logic/B05_Profile_Sections_Ground";
|
||||
|
||||
/** 서버 `sections/context` 의 표준 횡단(config) · 암 경계 기본 오프셋. */
|
||||
export interface ExpectStandard {
|
||||
standard: StandardCrossSectionSpec;
|
||||
rockBoundaryM: number | null;
|
||||
}
|
||||
|
||||
export interface ExpectCross {
|
||||
design: CrossDesignResult;
|
||||
/** 설계에 쓴 지반 표본(미교차로 넓혔으면 넓힌 것). */
|
||||
samples: CrossGroundPoint[];
|
||||
}
|
||||
|
||||
/** B 초기 설계 기본 — 리핑암 · 산쪽 절토(모르면 좌) · 일반 측구. */
|
||||
export function expectOptions(
|
||||
uphill: "left" | "right" | null,
|
||||
std: ExpectStandard,
|
||||
): CrossDesignOptions {
|
||||
return {
|
||||
groundType: "ripping_rock",
|
||||
sectionMode: `${uphill ?? "left"}_cut`,
|
||||
ditchType: "standard",
|
||||
standard: std.standard,
|
||||
rockBoundaryOffsetM: std.rockBoundaryM,
|
||||
};
|
||||
}
|
||||
|
||||
/** 측점 하나 예상 단면 — 지반고 · 표본이 없으면 null. */
|
||||
export function expectCross(
|
||||
station: StationGround,
|
||||
std: ExpectStandard,
|
||||
grid?: DtmGrid | null,
|
||||
): ExpectCross | null {
|
||||
const elevation = station.center_z;
|
||||
if (elevation === null) return null;
|
||||
const options = expectOptions(station.uphill_side, std);
|
||||
try {
|
||||
let samples = station.samples;
|
||||
let design = computeCrossDesign(samples, elevation, options);
|
||||
const wide =
|
||||
design.slope_unclosed && grid
|
||||
? extendUnclosed(
|
||||
samples,
|
||||
[station.center_x, station.center_y],
|
||||
station.left_xy,
|
||||
(next) => computeCrossDesign(next, elevation, options),
|
||||
grid,
|
||||
)
|
||||
: null;
|
||||
if (wide) {
|
||||
samples = wide.samples as CrossGroundPoint[];
|
||||
design = computeCrossDesign(samples, elevation, options);
|
||||
}
|
||||
return { design, samples };
|
||||
} catch {
|
||||
return null; // 표본 부족 — B 와 같은 태도(그 측점 건너뜀)
|
||||
}
|
||||
}
|
||||
|
||||
/** B06 `CrossSection` 중 `buildCorridor` 가 읽는 칸(B06 형 파일은 별칭 import 라 여기 안 끌어옴). */
|
||||
export interface ExpectSection {
|
||||
station_id: string;
|
||||
chainage_m: number;
|
||||
label: string;
|
||||
kind: "regular";
|
||||
center_z: number | null;
|
||||
azimuth_deg: null;
|
||||
center_x: number;
|
||||
center_y: number;
|
||||
uphill_side: "left" | "right" | null;
|
||||
frame: { left_xy: [number, number] };
|
||||
samples: CrossGroundPoint[];
|
||||
design: CrossDesignResult;
|
||||
}
|
||||
|
||||
/** 3D 코리도 입력 — 측점마다 예상 단면(못 세운 측점 뺌) · 누가 = 연도 노선 위 누가. */
|
||||
export function expectSections(
|
||||
stations: StationGround[],
|
||||
std: ExpectStandard,
|
||||
grid?: DtmGrid | null,
|
||||
): ExpectSection[] {
|
||||
return stations.flatMap((station) => {
|
||||
const cross = expectCross(station, std, grid);
|
||||
if (!cross) return [];
|
||||
return [
|
||||
{
|
||||
station_id: String(station.chainage_m),
|
||||
chainage_m: station.chainage_m,
|
||||
label: "",
|
||||
kind: "regular",
|
||||
center_z: station.center_z,
|
||||
azimuth_deg: null,
|
||||
center_x: station.center_x,
|
||||
center_y: station.center_y,
|
||||
uphill_side: station.uphill_side,
|
||||
frame: { left_xy: station.left_xy },
|
||||
samples: cross.samples,
|
||||
design: cross.design,
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user