feat(view): read the bearing ELEVATION TABLE from a DXF drawing (교각도(2) P1) by position
The reader takes TEXT and MTEXT entities (x, y, text). The EL.X header row names the columns; the No column holds the bearing numbers; each value is the nearest entry under its header on the same row. On the 운곡교 교각도(2) drawing all ten bearings read back the reference values (EL.X, h1, h2). The 도면 불러오기 button accepts .dxf as well as sheets. The test fixture holds only the table's text entries. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6f32bd96c4
commit
4048c326e3
4 files changed
+813
-10
No files matched your search
+23
-10
@@ -16,6 +16,7 @@ import { buildRebar3D, type RebarColorMode, type RebarScene } from './view/rebar
|
||||
import { DEFAULT_MATERIAL, FCK_MEMBERS, fyOf, GRADE_CHOICES, isAssumedMaterial, materialFrom, type BendFactors, type FckByMember, type FckMember, type GradeKey, type Material } from './core/rebar/common';
|
||||
import { buildQuantity, quantityRows, type Quantity, type QuantityLine } from './core/rebar/quantity';
|
||||
import { parseDrawingRows } from './core/drawing-import';
|
||||
import { parseBearingElevationTable, readDxfTexts } from './core/dxf-table';
|
||||
import { P1_COPING_GEOM } from './core/coping-geom';
|
||||
import { applyBearingRules, BEARING_ELEVATION_REF, BEARING_RULES_DEFAULT, type BearingBasis, type BearingRules, type DrawingBearing, DRAWING_TOL_MM, drawingCopingCheck, SOLPLATE_REF, SOLPLATE_T_RULE, solplateTs, withDrawingBasis } from './core/bearing-ref';
|
||||
|
||||
@@ -1341,24 +1342,36 @@ function renderBearingBasis(wrap: HTMLDivElement, pier: Pier): void {
|
||||
// 도면 불러오기 (승인 2026-10-23): a sheet with No, EL.X, h1, h2 (xlsx or csv) fills this pier's drawing values.
|
||||
const importInput = el('input');
|
||||
importInput.type = 'file';
|
||||
importInput.accept = '.xlsx,.xls,.csv';
|
||||
importInput.accept = '.xlsx,.xls,.csv,.dxf';
|
||||
importInput.id = 'drawing-import';
|
||||
importInput.addEventListener('change', async () => {
|
||||
const file = importInput.files?.[0];
|
||||
if (!file) return;
|
||||
try {
|
||||
const wb = XLSX.read(await file.arrayBuffer(), { type: 'array' });
|
||||
const sheet = wb.Sheets[wb.SheetNames[0]];
|
||||
const rows = XLSX.utils.sheet_to_json<unknown[]>(sheet, { header: 1, blankrows: false, defval: '' });
|
||||
const result = parseDrawingRows(rows);
|
||||
if (result.errors.length) {
|
||||
setError(`도면 불러오기 실패: ${result.errors.slice(0, 3).join(' ')}`);
|
||||
return;
|
||||
// A DXF drawing: the 교량받침 ELEVATION TABLE is read by position. Otherwise a sheet with No, EL.X, h1, h2.
|
||||
let drawingRows: DrawingBearing[];
|
||||
if (file.name.toLowerCase().endsWith('.dxf')) {
|
||||
const r = parseBearingElevationTable(readDxfTexts(await file.text()));
|
||||
if (r.errors.length) {
|
||||
setError(`도면 불러오기 실패: ${r.errors.slice(0, 3).join(' ')}`);
|
||||
return;
|
||||
}
|
||||
drawingRows = r.drawing;
|
||||
} else {
|
||||
const wb = XLSX.read(await file.arrayBuffer(), { type: 'array' });
|
||||
const sheet = wb.Sheets[wb.SheetNames[0]];
|
||||
const rows = XLSX.utils.sheet_to_json<unknown[]>(sheet, { header: 1, blankrows: false, defval: '' });
|
||||
const r = parseDrawingRows(rows);
|
||||
if (r.errors.length) {
|
||||
setError(`도면 불러오기 실패: ${r.errors.slice(0, 3).join(' ')}`);
|
||||
return;
|
||||
}
|
||||
drawingRows = r.rows;
|
||||
}
|
||||
bearingDrawing = { ...bearingDrawing, [name]: result.rows };
|
||||
bearingDrawing = { ...bearingDrawing, [name]: drawingRows };
|
||||
regenerateAllPiers();
|
||||
renderAll();
|
||||
setStatus(`${file.name}에서 받침 ${result.rows.length}개의 도면 값을 불러왔습니다.`);
|
||||
setStatus(`${file.name}에서 받침 ${drawingRows.length}개의 도면 값을 불러왔습니다.`);
|
||||
} catch (err) {
|
||||
setError(`도면 파일을 읽지 못했습니다: ${(err as Error).message}`);
|
||||
} finally {
|
||||
|
||||
Reference in new issue
Block a user