diff --git a/B07_DesignDetail/B07_DesignDetail_Engine_Cad_Standard.py b/B07_DesignDetail/B07_DesignDetail_Engine_Cad_Standard.py index ce03210cd..9637e3391 100644 --- a/B07_DesignDetail/B07_DesignDetail_Engine_Cad_Standard.py +++ b/B07_DesignDetail/B07_DesignDetail_Engine_Cad_Standard.py @@ -141,7 +141,7 @@ def _section_geometry(values: dict[str, Any]) -> dict[str, Any]: bottom_width = _number(ditch.get("bottom_width_m"), 0.3) depth = _number(ditch.get("depth_m"), 0.3) slope = values.get("cross_slope_pct") if isinstance(values.get("cross_slope_pct"), dict) else {} - cross_pct = _number(slope.get("max"), _number(slope.get("min"), 3.0)) + cross_pct = _number(slope.get("min"), _number(slope.get("max"), 3.0)) cut_ratio = _number(values.get("cut_slope_ratio"), 1.0) fill_ratio = _number(values.get("fill_slope_ratio"), 1.2) diff --git a/B07_DesignDetail/B07_DesignDetail_Router.py b/B07_DesignDetail/B07_DesignDetail_Router.py index 5234dfcfb..a98ee1c99 100644 --- a/B07_DesignDetail/B07_DesignDetail_Router.py +++ b/B07_DesignDetail/B07_DesignDetail_Router.py @@ -359,7 +359,7 @@ async def get_design_drawing( source_design = ((section or {}).get("data") or {}).get("mass_haul") elif drawing_id == CROSS_STANDARD_ID: # 표준 횡단면도는 B06 「표준 횡단면 설정」 저장값으로 그린다(없으면 config 기본값). - source_design = await standard_cross_source(project_id) + source_design = await standard_cross_source(project_id, route_id) elif DEVELOPMENT_ID.fullmatch(drawing_id): # 전개도 — 추가 흙막이 단 수 · 포장 빈 폭을 측점별 설계에서 읽음(377) source_design = await _designs_by_chainage(route_id) diff --git a/B07_DesignDetail/B07_DesignDetail_Router_Support_Fingerprint.py b/B07_DesignDetail/B07_DesignDetail_Router_Support_Fingerprint.py index a18a03b23..4398ee4e1 100644 --- a/B07_DesignDetail/B07_DesignDetail_Router_Support_Fingerprint.py +++ b/B07_DesignDetail/B07_DesignDetail_Router_Support_Fingerprint.py @@ -354,22 +354,18 @@ async def plan_copy_key( return prints[drawing_id]["fingerprint"] -async def standard_cross_source(project_id: UUID) -> Any: - """표준 횡단면 설정(B06) — GET 과 지문이 같은 값을 씀.""" - from B06_Section.B06_Section_Repository import get_project_standard_cross_section +async def standard_cross_source(project_id: UUID, route_id: int) -> Any: + """그리는 노선의 표준 횡단면 설정(B06) — GET 과 지문이 같은 값을 씀.""" + from B06_Section.B06_Section_Repository import get_longitudinal_section from config.config_db import get_db_pool pool = get_db_pool() async with pool.acquire() as connection: - async with connection.cursor() as cursor: - await cursor.execute( - "SELECT company_id FROM projects WHERE id = %s AND deleted_at IS NULL", - (str(project_id),), - ) - row = await cursor.fetchone() - if not row: - return None - return await get_project_standard_cross_section(connection, int(row[0]), project_id) + section = await get_longitudinal_section(connection, project_id, route_id) + data = (section or {}).get("data") or {} + options = data.get("options") if isinstance(data, dict) else None + standard = options.get("standard_cross_section") if isinstance(options, dict) else None + return standard if isinstance(standard, dict) else None async def drawing_fingerprints( @@ -424,7 +420,7 @@ async def drawing_fingerprints( async def read_standard() -> None: if _STANDARD_ID in ids: - sources["standard"] = await standard_cross_source(project_id) + sources["standard"] = await standard_cross_source(project_id, route_id) async def read_cross() -> None: if not has_sheet: diff --git a/resources/tester/test_517_1_b07_standard_cross.py b/resources/tester/test_517_1_b07_standard_cross.py new file mode 100644 index 000000000..5836d20ea --- /dev/null +++ b/resources/tester/test_517_1_b07_standard_cross.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +"""517-1 B07 표준 횡단면도 = 그리는 노선의 B06 저장값.""" + +from __future__ import annotations + +import asyncio +import sys +from pathlib import Path +from types import SimpleNamespace +from uuid import uuid4 + +ROOT = Path(__file__).resolve().parents[2] +if str(ROOT) not in sys.path: + sys.path.insert(0, str(ROOT)) + +from B06_Section import B06_Section_Repository as b06_repository # noqa: E402 +from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Standard import ( # noqa: E402 + MM, + SECTION_LAYER_ID, + build_standard_cross_drawing, +) +from B07_DesignDetail import B07_DesignDetail_Router_Support_Fingerprint as fp # noqa: E402 +from config import config_db # noqa: E402 + + +def _standard(cross_slope_pct: float) -> dict: + return { + "soil": { + "road_width_m": 3.0, + "shoulder_left_m": 0.5, + "shoulder_right_m": 0.5, + "cross_slope_pct": {"min": cross_slope_pct, "max": 5.0}, + } + } + + +def test_B06_저장값_3퍼센트로_표준도_선과_숫자를_그림(): + drawing = build_standard_cross_drawing("cross_standard", "표준 횡단면도", _standard(3.0)) + labels = [ + entity["shapeData"]["label"] for entity in drawing["entities"] if entity["type"] == "Text" + ] + assert "횡단경사 3%" in labels + + outline = next( + entity + for entity in drawing["entities"] + if entity["type"] == "PolyLine" and entity["layerId"] == SECTION_LAYER_ID + ) + road = next( + child["shapeData"] + for child in outline["children"] + if child["shapeData"]["startPoint"]["x"] == -2.0 * MM + and child["shapeData"]["endPoint"]["x"] == 2.0 * MM + ) + assert road["startPoint"]["y"] == -2.0 * MM * 0.03 + assert road["endPoint"]["y"] == 0.0 + + +class _Acquire: + async def __aenter__(self): + return object() + + async def __aexit__(self, *exc): + return False + + +class _Pool: + def acquire(self): + return _Acquire() + + +def test_노선_둘이면_그리는_노선의_B06_저장값만_읽음(monkeypatch): + standards = {11: _standard(4.0), 22: _standard(3.0)} + + async def get_section(_connection, _project_id, route_id): + return {"data": {"options": {"standard_cross_section": standards[route_id]}}} + + monkeypatch.setattr(b06_repository, "get_longitudinal_section", get_section) + monkeypatch.setattr(config_db, "get_db_pool", lambda: _Pool()) + + source = asyncio.run(fp.standard_cross_source(uuid4(), 22)) + assert source["soil"]["cross_slope_pct"]["min"] == 3.0 + + +def test_표준도_지문도_그리는_노선값을_씀(monkeypatch, tmp_path): + calls = [] + + async def standard_source(_project_id, route_id): + calls.append(route_id) + return _standard(3.0) + + def fingerprints(_root, _longitudinal, _drawings, sources): + return {"standard": sources["standard"]} + + monkeypatch.setattr(fp, "standard_cross_source", standard_source) + monkeypatch.setattr(fp, "compute_fingerprints", fingerprints) + result = asyncio.run( + fp.drawing_fingerprints( + uuid4(), + 22, + tmp_path, + tmp_path / "longitudinal.json", + [SimpleNamespace(id="cross_standard", kind="cross_standard")], + {}, + ) + ) + assert calls == [22] + assert result["standard"]["soil"]["cross_slope_pct"]["min"] == 3.0