feat(B05/B06): 유토곡선 횡단 기준 통일·자동선정 삭제·계획선 R 연결 외 9건
사용자 피드백 반영(2026-08-03 2차).
유토곡선 일원화
- B05 유토곡선을 B06과 같은 계산(computeMassHaulSeries: 횡단 정식 + 종단 개략
비교)으로 전환. 상세 조회가 미지정 측점에 기본 설계를 즉석 계산해 얹으므로
B05 진입 시점에 이미 정식 곡선 재료가 있다. 표시 토글 sessionStorage 키와
balloon 위치 scope를 B06과 공유해 두 화면이 같은 그림을 유지한다.
- B05 전용 개략 엔진(computeLongitudinalMassHaul) 삭제.
- 유토곡선 펼침 시 종단 그래프:곡선 세로 1:1 분할.
사토장·토취장 자동 선정 삭제
- 임도에는 토취장이 없고 부족분은 설계자가 계획선을 고쳐 맞춘다는 실무 판단에
따라 4옵션(비용/지형안정성/계곡부/임내공간) 엔진·API·UI·config·저장 훅 전부
제거. massHaulPayload/createMassHaulLegend 시그니처 원복.
기본 지반 변경
- 기본 설계 프리뷰·확정 기본값을 토사에서 리핑암 + 예상 암반 경계 0.5m로 변경.
산지 절토는 표토 아래 암이 일반적이라 전량 토사 가정은 물량이 낙관적이다.
발파암은 B06에서 측점별 수정.
계획선 R·선 연결 (배관 구조물 자리)
- 계획선 샘플이 고정 격자로만 평가되어 격자 사이 변화점(배관 측점 승격분)의
모서리를 잘라먹던 결함 수정 — 샘플 집합에 PVI·BVC·EVC를 합집합으로 포함
(프론트 buildAlignment + 서버 build_alignment 동일 규칙). 면적 가중치도
합쳐진 격자로 재계산. 37.3m 변화점 + R=150 수치 검증 통과.
표시 개선
- EP(종점) 잔량 라벨: 곡선 끝점에 "EP {누가토량}㎥" 불투명 판(B05·B06 공통).
- 유토곡선 0선을 붉은 굵은 실선(2.5px)으로, 0 눈금값도 적색.
- 3D 뷰 [측점 가로선] 우측 [측점 라벨] 토글 신설(기본 꺼짐) — 구조물 측점만
"측점번호 구조물명" 스프라이트 표시.
typecheck·vite build·ruff·B03 테스트 통과. 실서버 스모크로 리핑암 기본 프리뷰와
disposal-sites 제거 확인.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -392,61 +392,6 @@ function longitudinalAreaSamples(
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 횡단 설계가 아직 없을 때 쓰는 종단 개략 곡선의 입력.
|
||||
*
|
||||
* B05 노선 설계 단계에는 측점별 횡단 설계(`CrossDesign`)가 없다 — 그건 B06에서 만든다.
|
||||
* 그래서 노반폭을 표준횡단 설정(`road_width_m + shoulder_left_m + shoulder_right_m`)에서
|
||||
* 한 값으로 받아 전 구간에 같게 물린다. 계획선을 끌어 옮기며 절·성토 균형을 잡는
|
||||
* 용도라 이 정도 개략값이면 충분하고, 정식 물량은 B06 횡단 기준 곡선이 낸다.
|
||||
*/
|
||||
export interface LongitudinalMassHaulOptions {
|
||||
/** 전 구간 공통 노반폭(m). */
|
||||
roadbedWidthM: number;
|
||||
/**
|
||||
* 절토 전량에 물릴 지반유형. B05는 암반 경계선을 모르므로 기본값은 토사이며,
|
||||
* 그만큼 다짐환산이 보수적으로(작게) 잡힌다.
|
||||
*/
|
||||
groundType?: GroundType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 횡단 설계 없이 종단 계획선만으로 개략 유토곡선을 만든다(B05 계획 단계).
|
||||
*
|
||||
* `difference_m = 계획고 − 지반고`이므로 음수면 절토, 양수면 성토다. 단면적은 그 높이차에
|
||||
* 노반폭을 곱한 사각형으로 어림한다 — 비탈면 몫이 빠져 실제보다 작게 나오지만, 국내
|
||||
* 설계기준이 종단 기반 토량을 노선계획 단계의 **개산용**으로만 두고 별도 산식을 정하지
|
||||
* 않으므로(2026-08-03 조사) 표준단면까지 씌워 정밀화하지는 않는다.
|
||||
* 자연방토는 성토측 지반 경사를 알 수 없어 전부 불가로 본다(보수적).
|
||||
*/
|
||||
export function computeLongitudinalMassHaul(
|
||||
longitudinal: MassHaulLongitudinal,
|
||||
conversion: EarthworkConversion,
|
||||
options: LongitudinalMassHaulOptions,
|
||||
): MassHaulResult | null {
|
||||
const profile = longitudinal.design_profiles?.[0];
|
||||
const width = finiteArea(options.roadbedWidthM);
|
||||
if (!profile || !(width > 0)) return null;
|
||||
const ground = normalizeGround(options.groundType);
|
||||
const samples = profile.samples
|
||||
.filter((sample) => Number.isFinite(sample.chainage_m) && Number.isFinite(sample.difference_m))
|
||||
.sort((a, b) => a.chainage_m - b.chainage_m);
|
||||
const areas: AreaSample[] = samples.map((sample, index) => {
|
||||
const height = sample.difference_m;
|
||||
const cutArea = height < 0 ? -height * width : 0;
|
||||
return {
|
||||
station_id: `plan@${index}`,
|
||||
chainage_m: sample.chainage_m,
|
||||
cut_soil_area_m2: ground === "soil" ? cutArea : 0,
|
||||
cut_rock_area_m2: ground === "soil" ? 0 : cutArea,
|
||||
rock_kind: ground === "soil" ? null : ground,
|
||||
fill_area_m2: height > 0 ? height * width : 0,
|
||||
natural_spoil: false,
|
||||
};
|
||||
});
|
||||
return integrate(areas, conversion);
|
||||
}
|
||||
|
||||
/**
|
||||
* 측점별 설계 결과에서 유토곡선을 계산한다(횡단 기준·지반유형별 환산).
|
||||
* 확정 저장과 B08 인계에 쓰는 **정식 곡선**이라 시그니처를 그대로 유지한다.
|
||||
@@ -493,16 +438,12 @@ export function massHaulPayload(
|
||||
result: MassHaulResult,
|
||||
haulPlan?: HaulPlan | null,
|
||||
balloonOffsets?: Record<string, [number, number]>,
|
||||
/** B05가 고른 사토장·토취장 — 정식 곡선 기준으로 운반거리를 다시 잰 형태로 받는다. */
|
||||
disposalSites?: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
const round = (value: number): number => Math.round(value * 100) / 100;
|
||||
return {
|
||||
basis: "compacted",
|
||||
conversion: result.conversion,
|
||||
...(haulPlan ? { haul_plan: haulPlanPayload(haulPlan) } : {}),
|
||||
// B08 내역서가 사토·토취 운반 항목을 세우는 입력. 선정이 없으면 키 자체가 빠진다.
|
||||
...(disposalSites ? { disposal_sites: disposalSites } : {}),
|
||||
// 사용자가 끌어 옮긴 balloon 위치 — 비어 있어도 보낸다(초기화가 저장에 반영돼야 한다).
|
||||
...(balloonOffsets ? { balloon_offsets: balloonOffsets } : {}),
|
||||
cut_natural_m3: {
|
||||
|
||||
Reference in New Issue
Block a user