Files
SPipe/backend/tests/test_drawing_ezdxf.py
SPipe EngineeringandClaude Opus 5.5 e3f386addf 도면 출력 추가: 수리 종단면도, 관망도(색인도·부분도·수압표), 범례·색상 선택, DXF(AutoCAD 2018)
- 데모 v2 이후 개발 PC의 변경을 옮김 (이 저장소의 이름 변경·README 정리는 유지)
- 서버 기본 DEM, DEM 등고선, 속성 테이블 범위 선택, WNTR 교차 검증 시험 포함
- 새 라이브러리: ezdxf(Python), maplibre-contour(npm)
- 변경 내역: docs/SPipe_패치내역_도면출력_2026-11-06.txt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 15:03:21 +09:00

57 lines
2.7 KiB
Python

"""Drawing sheet -> DXF R2018 (ezdxf): Unicode text, layers, lineweights, hatches."""
import io
import os
import tempfile
import ezdxf
import pyogrio
import pytest
from fastapi.testclient import TestClient
from backend.batch import BatchError
from backend.drawing_dxf import drawing_to_dxf
from backend.main import app
DRAWING = {
"width": 420, "height": 297, "title": "t",
"items": [
{"kind": "line", "layer": "FRAME", "pts": [[0, 0], [420, 0], [420, 297], [0, 297]], "closed": True, "width": 0.7},
{"kind": "line", "layer": "HGL_1", "pts": [[50, 200], [300, 150]], "width": 0.45, "color": "#1d4ed8", "dash": "dashed"},
{"kind": "fill", "layer": "LEGEND", "pts": [[10, 10], [30, 10], [30, 20], [10, 20]], "fill": "#ffffff", "opacity": 0.9},
{"kind": "circle", "layer": "NODE", "x": 100, "y": 100, "r": 1.2, "fill": "#dc2626", "color": "#dc2626"},
{"kind": "text", "layer": "TITLE", "x": 210, "y": 280, "text": "송수관로 수리 종단면도 ○ ‰ m³", "size": 7, "anchor": "middle", "vAnchor": "middle", "bold": True},
{"kind": "text", "layer": "TABLE", "x": 60, "y": 60, "text": "J-101", "size": 2, "rotate": 90, "anchor": "middle", "vAnchor": "middle"},
],
}
def test_r2018_with_unicode_layers_and_styles():
data = drawing_to_dxf(DRAWING)
doc = ezdxf.read(io.StringIO(data.decode("utf-8")))
assert doc.dxfversion == "AC1032" and doc.units == ezdxf.units.MM
msp = doc.modelspace()
texts = [e.dxf.text for e in msp.query("TEXT")]
assert "송수관로 수리 종단면도 ○ ‰ m³" in texts
hgl = msp.query('LWPOLYLINE[layer=="HGL_1"]')[0]
assert hgl.dxf.linetype == "DASHED" and hgl.dxf.lineweight == 40 and hgl.rgb == (29, 78, 216)
assert len(msp.query("HATCH")) == 1 and len(msp.query("CIRCLE")) == 1 # white mask box dropped
assert {"FRAME", "HGL_1", "NODE", "TITLE", "TABLE"} <= {l.dxf.name for l in doc.layers}
rotated = [e for e in msp.query("TEXT") if e.dxf.text == "J-101"][0]
assert rotated.dxf.rotation == 90
# GDAL (what GIS tools use) reads the Korean text back too.
with tempfile.TemporaryDirectory() as tmp:
p = os.path.join(tmp, "d.dxf")
open(p, "wb").write(data)
meta, _, _, fields = pyogrio.raw.read(p)
gtexts = [t for t in fields[list(meta["fields"]).index("Text")] if t]
assert any("송수관로" in t for t in gtexts)
def test_errors_and_endpoint():
with pytest.raises(BatchError):
drawing_to_dxf({"items": []})
with TestClient(app) as c:
r = c.post("/api/drawing/dxf", json={"drawing": DRAWING, "name": "종단면도"})
assert r.status_code == 200 and b"AC1032" in r.content
assert "송수관로".encode("utf-8") in r.content