feat(abut): 교대 지반·지층 카드 — 교각과 같은 위치 · 수위 · 지층 행 입력, 교대 단면 삽도, 검사
- 위치 (육상 · 하상 · 해상)와 위치별 수위 입력, 지층 행 표 (교각과 공용 strataRowsEditor), 지반 모델 지층 불러오기 - 검사: 교각과 같은 G01–G14, 말뚝 근입 G04, 지반고 < 저판 하면이면 정보 AI01 - 삽도: 지층 · 수위 띠를 교각과 공용으로 빼고, 교대축 직각 단면(저판 · 벽체 · 흉벽 · 말뚝 열)을 EL. 표기로 그림 - 자동 값: 지반고 (엑셀 입력), 연암층 상면 EL, 지층 수. 프로젝트 파일 저장 · 검증 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9835fb42b3
commit
59c2607418
12 files changed
+527
-135
No files matched your search
@@ -0,0 +1,71 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import * as XLSX from 'xlsx';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildAbut } from '../src/core/abut/geometry';
|
||||
import { parseAbutments, toAbutInput, type AbutRecord } from '../src/core/abut/parse';
|
||||
import { buildMembers } from '../src/core/abut/members';
|
||||
import { setAbutGround } from '../src/core/abut/edit';
|
||||
import { abutGroundChanged, abutGroundIssues, supportTopEl } from '../src/core/abut/ground';
|
||||
import { abutMemberRows } from '../src/core/abut/member-list';
|
||||
import { checkStoredAbutments } from '../src/core/project';
|
||||
import { abutGroundSectionSvg } from '../src/view/ground-svg';
|
||||
|
||||
const RAG = fileURLToPath(new URL('../../../RAG/운곡교P1입력.xlsx', import.meta.url));
|
||||
const rec = parseAbutments(XLSX.read(readFileSync(RAG), { type: 'buffer' })).abutments[0];
|
||||
const membersOf = (r: AbutRecord) => buildMembers(buildAbut(toAbutInput(r)), { bottomEl: r.foundationBottomEl, pileLengthMm: r.pileLengthMm }, r.shape);
|
||||
const codes = (r: AbutRecord) => abutGroundIssues(r, membersOf(r)).map((i) => i.code);
|
||||
// A1: 지반고 33.984, 기초 하단 40.895, 말뚝 선단 19.295 (spec_abut §12).
|
||||
const rows = [
|
||||
{ name: '퇴적토', bottomEl: 30 },
|
||||
{ name: '풍화암', bottomEl: 22 },
|
||||
{ name: '연암', bottomEl: 10 },
|
||||
];
|
||||
|
||||
describe('교대 지반·지층 (2026-11-04, 교각 카드와 같은 입력)', () => {
|
||||
it('defaults: 육상, no water, no rows; only AI01 (지반고 below the 저판 하면) is reported', () => {
|
||||
expect(codes(rec)).toEqual(['AI01']);
|
||||
expect(abutGroundIssues(rec, membersOf(rec))[0].message).toContain('6.911');
|
||||
expect(abutGroundChanged(rec.ground)).toBe(false);
|
||||
});
|
||||
|
||||
it('the pier checks apply: G01 order, G02 water, G07 DHWL, G13 sea, G04 pile embedment into the 연암', () => {
|
||||
expect(codes(setAbutGround(rec, { strataRows: [{ name: '퇴적토', bottomEl: 35 }] }))).toContain('G01');
|
||||
expect(codes(setAbutGround(rec, { groundWaterOn: true }))).toContain('G02');
|
||||
expect(codes(setAbutGround(rec, { groundPosition: '하상' }))).toContain('G07');
|
||||
expect(codes(setAbutGround(rec, { groundPosition: '해상' }))).toContain('G13');
|
||||
// 연암 상면 22.000 − 1.0 × 0.6 = 21.4; the tip 19.295 is deep enough.
|
||||
expect(codes(setAbutGround(rec, { strataRows: rows }))).toEqual(['AI01']);
|
||||
const shallow = setAbutGround(rec, { strataRows: [{ name: '풍화암', bottomEl: 19.5 }, { name: '연암', bottomEl: 10 }] });
|
||||
expect(codes(shallow)).toContain('G04');
|
||||
expect(supportTopEl(rec.groundEl, rows)).toBe(22);
|
||||
expect(supportTopEl(rec.groundEl, [{ name: '퇴적토', bottomEl: 30 }])).toBeUndefined();
|
||||
});
|
||||
|
||||
it('set: merges values, removes undefined, refuses non-numbers; the member row follows', () => {
|
||||
const a = setAbutGround(rec, { groundPosition: '하상', floodLevelEl: 36 });
|
||||
expect(setAbutGround(a, { floodLevelEl: undefined }).ground).toEqual({ groundPosition: '하상' });
|
||||
expect(() => setAbutGround(rec, { groundWaterEl: Number.NaN })).toThrow('숫자');
|
||||
const row = abutMemberRows(setAbutGround(rec, { strataRows: rows }), '—').find((r) => r.id === 'ground')!;
|
||||
expect(row.summary).toBe('육상 · 지층 3 · 지반고 EL.33.984');
|
||||
expect(row.changed).toBe(true);
|
||||
});
|
||||
|
||||
it('the project file keeps the 지반 values and refuses wrong ones', () => {
|
||||
expect(() => checkStoredAbutments([setAbutGround(rec, { groundPosition: '해상', highWaterEl: 35, strataRows: rows })])).not.toThrow();
|
||||
expect(() => checkStoredAbutments([{ ...rec, ground: { groundPosition: '산지' } as never }])).toThrow('지반');
|
||||
expect(() => checkStoredAbutments([{ ...rec, ground: { strataRows: [{ name: '연암', bottomEl: 'x' }] } as never }])).toThrow('지반');
|
||||
});
|
||||
|
||||
it('삽도: layers, water and the abutment section with EL. labels', () => {
|
||||
const m = membersOf(rec);
|
||||
const s = m.shape;
|
||||
const svg = abutGroundSectionSvg({
|
||||
ground: { groundEl: rec.groundEl, groundWaterOn: true, groundWaterEl: 31, strataRows: rows },
|
||||
footingTopEl: m.footingTopEl, footingBottomEl: m.footingBottomEl!, seatEl: rec.seatEl, parapetTopEl: m.parapetTopStartEl,
|
||||
bracketHeightM: s.bracketHeightM, wallFrontM: s.wallFrontM, wallBackM: s.wallBackM, parapetBackM: s.parapetBackM,
|
||||
footingFrontM: s.footingFrontM, footingBackM: s.footingBackM, pileRowsT: m.piles.map((r) => r.t), pileBottomEl: m.pileBottomEl,
|
||||
});
|
||||
for (const t of ['지반고 EL.33.984', '지하수위 EL.31.000', '연암층 상면 EL.22.000', '기초 하단 EL.40.895', '말뚝 선단 EL.19.295', '퇴적토', '풍화암']) expect(svg).toContain(t);
|
||||
});
|
||||
});
|
||||
@@ -42,10 +42,10 @@ describe('교대 부재 목록 (시안 ② 부재 · 교대)', () => {
|
||||
it('shows the slab width text and the ground EL as given', () => {
|
||||
const rows = abutMemberRows(base, '11.253 m');
|
||||
expect(rows.find((r) => r.id === 'slab')?.summary).toBe('매립형 · 하향 4 % · 폭 11.253 m');
|
||||
expect(rows.find((r) => r.id === 'ground')?.summary).toBe('지반고 33.984 m');
|
||||
expect(rows.find((r) => r.id === 'ground')?.summary).toBe('육상 · 지층 0 · 지반고 EL.33.984');
|
||||
});
|
||||
|
||||
it('every card but the ground takes input in this step (접속슬래브 2026-11-04)', () => {
|
||||
expect(ABUT_MEMBER_EDITABLE).toEqual({ bearing: true, shape: true, footing: true, wing: true, slab: true, ground: false });
|
||||
it('every card takes input in this step (접속슬래브 · 지반 2026-11-04)', () => {
|
||||
expect(ABUT_MEMBER_EDITABLE).toEqual({ bearing: true, shape: true, footing: true, wing: true, slab: true, ground: true });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user