fix(B07): 횡단도 노란 측구 덧그림 걷음 · 배수관 · 박스암거 덧그림 색 따로(268)
- 측구 구간 구조물 선(b08-structure)도 design_ids 에 실음 — 화면 구조물 덧그림이 같은 자리를 그릴 때 서버 노란 측구가 한 겹 더 남던 것 걷음 (장 · 단일 도면) - 박스암거 · 배수관 덧그림을 구조물(노랑)과 다른 청록(#22d3ee)으로 — 설계선 보라 · 지반선과 구분 - 시험 test_268_b07_cross_ditch_pipe_color.py Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SE9MxeXTu2uaDZ55BJowAY
This commit is contained in:
@@ -29,6 +29,8 @@ const SVG_NS = "http://www.w3.org/2000/svg";
|
||||
/** 구조물 엔티티가 들어갈 레이어·색 — 서버 도면이 이미 선언해 둔 그 레이어다. */
|
||||
const STRUCTURE_LAYER_ID = "b08-structure";
|
||||
const STRUCTURE_COLOR = "#f6d55c";
|
||||
/** 배수관 · 박스암거 색 — 구조물(노랑) · 설계선(보라) · 지반선(흰/검정)과 또렷이 다른 청록(268-2). */
|
||||
const PIPE_COLOR = "#22d3ee";
|
||||
/** 설계선 도면층·색 — 서버 도면(`B07_DesignDetail_Engine_Cad`)이 쓰는 그 값이다. */
|
||||
export const DESIGN_LAYER_ID = "b08-design";
|
||||
const DESIGN_COLOR = "#b794f6";
|
||||
@@ -49,6 +51,7 @@ interface Style {
|
||||
}
|
||||
|
||||
const STRUCTURE_STYLE: Style = { layerId: STRUCTURE_LAYER_ID, color: STRUCTURE_COLOR };
|
||||
const PIPE_STYLE: Style = { layerId: STRUCTURE_LAYER_ID, color: PIPE_COLOR };
|
||||
const DESIGN_STYLE: Style = { layerId: DESIGN_LAYER_ID, color: DESIGN_COLOR };
|
||||
|
||||
function baseEntity(style: Style, type: string, shapeData: unknown): Entity {
|
||||
@@ -494,9 +497,10 @@ function drawDesign(
|
||||
);
|
||||
}
|
||||
|
||||
/** 구조물을 그린다. 그리는 순서는 B06 카드와 같다. */
|
||||
/** 구조물을 그린다. 그리는 순서는 B06 카드와 같다 — 박스암거 · 배수관은 pipeSvg 로 따로(268-2). */
|
||||
function drawStructures(
|
||||
svg: SVGElement,
|
||||
pipeSvg: SVGElement,
|
||||
section: CrossSection,
|
||||
layouts: Layouts,
|
||||
x: (offset: number) => number,
|
||||
@@ -504,12 +508,12 @@ function drawStructures(
|
||||
): void {
|
||||
const { link, culvert, box, ford, own } = layouts;
|
||||
if (own) appendRevetmentOverlay(svg, own, x, y);
|
||||
if (box) appendBoxOverlay(svg, box, x, y);
|
||||
if (box) appendBoxOverlay(pipeSvg, box, x, y);
|
||||
if (ford) appendFordOverlay(svg, ford, x, y);
|
||||
if (culvert) {
|
||||
const linked = !section.culvert && !!link;
|
||||
appendCulvertOverlay(
|
||||
svg,
|
||||
pipeSvg,
|
||||
culvert,
|
||||
x,
|
||||
y,
|
||||
@@ -536,9 +540,11 @@ export function overlayEntities(
|
||||
const designSvg = document.createElementNS(SVG_NS, "svg");
|
||||
drawDesign(designSvg, section, layouts, x, y);
|
||||
const structureSvg = document.createElementNS(SVG_NS, "svg");
|
||||
drawStructures(structureSvg, section, layouts, x, y);
|
||||
const pipeSvg = document.createElementNS(SVG_NS, "svg");
|
||||
drawStructures(structureSvg, pipeSvg, section, layouts, x, y);
|
||||
return [
|
||||
...harvest(designSvg, DESIGN_STYLE, frame),
|
||||
...harvest(structureSvg, STRUCTURE_STYLE, frame),
|
||||
...harvest(pipeSvg, PIPE_STYLE, frame),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -628,6 +628,12 @@ def build_cross_drawing(
|
||||
# 블록 테두리(종이 mm). 프론트가 자기 그림을 이 안으로 자르고, 갈아 끼울
|
||||
# 서버 설계선을 이 안에서만 골라내는 데 쓴다.
|
||||
"frame": [frame_left, frame_bottom, frame_right, frame_top],
|
||||
# 화면이 다시 그려 갈아 끼울 서버 선 — 설계선 + 측구 구간 구조물 선(268-1)
|
||||
"design_ids": [
|
||||
e["id"]
|
||||
for e in entities
|
||||
if e["layerId"] in (DESIGN_LAYER_ID, STRUCTURE_LAYER_ID)
|
||||
],
|
||||
}
|
||||
],
|
||||
"layers": [
|
||||
|
||||
@@ -240,7 +240,9 @@ def build_cross_sheet(sheet: dict[str, Any], sections: list[dict[str, Any]]) ->
|
||||
layer_id = f"{STATION_LAYER_PREFIX}{section['chainage']}"
|
||||
title = section.get("title") or f"{section['chainage']}"
|
||||
station_layers.append(_layer(layer_id, f"횡단 {title}"))
|
||||
design_ids = [e["id"] for e in placed["entities"] if e["layerId"] == DESIGN_LAYER_ID]
|
||||
# 측구 구간 구조물 선(b08-structure)도 갈아 끼울 대상 — 화면 구조물 덧그림이 같은 자리를 그림(268-1)
|
||||
replaceable = (DESIGN_LAYER_ID, STRUCTURE_LAYER_ID)
|
||||
design_ids = [e["id"] for e in placed["entities"] if e["layerId"] in replaceable]
|
||||
for entity in placed["entities"]:
|
||||
_move_to_layer(entity, layer_id)
|
||||
for placement in placed.get("cross_placements") or []:
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""268 B07 횡단도 — 노란 측구 덧그림 · 배수관 · 박스암거 색.
|
||||
|
||||
못박는 것
|
||||
- 268-1 측구 구간 구조물 선(b08-structure)도 design_ids 에 실려 화면 덧그림이 갈아 끼울 때 걷힘
|
||||
(장 · 단일 도면 모두) · 설계선 · 측구 본 그림(구조물 선 자체)은 그대로 남음.
|
||||
- 268-2 박스암거 · 배수관 덧그림은 구조물(노랑) · 설계선(보라) · 지반선과 다른 색 한 벌.
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from B07_DesignDetail.B07_DesignDetail_Engine_Cad import (
|
||||
DESIGN_COLOR,
|
||||
DESIGN_LAYER_ID,
|
||||
GROUND_COLOR,
|
||||
ROCK_COLOR,
|
||||
STRUCTURE_COLOR,
|
||||
STRUCTURE_LAYER_ID,
|
||||
build_cross_drawing,
|
||||
)
|
||||
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import build_cross_sheet, plan_cross_sheets
|
||||
from B07_DesignDetail.B07_DesignDetail_Engine_Template import use_project_templates
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
_DESIGN = {
|
||||
"ditch_enabled": True,
|
||||
"ditch_side": "left",
|
||||
"ditch": {"type": "standard", "top_width_m": 1.0},
|
||||
"road_edges": {"left": {"offset_m": -1.0}},
|
||||
}
|
||||
_LINE = [
|
||||
{"offset_m": x, "elevation_m": 100.0 + (0.0 if x >= -1.0 else -0.3)}
|
||||
for x in (-3.0, -2.0, -1.0, 0.0, 3.0)
|
||||
]
|
||||
|
||||
|
||||
def _source(chainage: float) -> dict:
|
||||
return {
|
||||
"chainage_m": chainage,
|
||||
"samples": [
|
||||
{"valid": True, "offset_m": float(x), "elevation_m": 100.0 + 0.1 * x}
|
||||
for x in range(-5, 6)
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def _ditch_ids(entities: list[dict]) -> list[str]:
|
||||
return [e["id"] for e in entities if e["lineColor"] == STRUCTURE_COLOR]
|
||||
|
||||
|
||||
def test_측구_구조물_선_design_ids_장() -> None:
|
||||
use_project_templates(None)
|
||||
sheet = plan_cross_sheets([0.0, 20.0], {"default": [2, 1]})[0]
|
||||
sections = [
|
||||
{
|
||||
"chainage": c,
|
||||
"source": _source(c),
|
||||
"design": _DESIGN,
|
||||
"design_line": _LINE,
|
||||
"quantity_table": {"ground": 1.0, "planned": 0.5},
|
||||
"title": f"No.{int(c // 20)}",
|
||||
}
|
||||
for c in (0.0, 20.0)
|
||||
]
|
||||
drawing = build_cross_sheet(sheet, sections)
|
||||
by_id = {e["id"]: e for e in drawing["entities"]}
|
||||
ditch = _ditch_ids(drawing["entities"])
|
||||
assert len(ditch) == 2 # 측점마다 측구 구간 선 하나
|
||||
for placement in drawing["cross_placements"]:
|
||||
ids = placement["design_ids"]
|
||||
assert len(set(ids) & set(ditch)) == 1 # 자기 측점 측구 선만
|
||||
assert all(by_id[i]["lineColor"] in (DESIGN_COLOR, STRUCTURE_COLOR) for i in ids)
|
||||
# 걷기는 화면이 하고, 서버 도면은 측구 구조물 선을 그대로 가짐
|
||||
assert all(by_id[i]["lineColor"] == STRUCTURE_COLOR for i in ditch)
|
||||
|
||||
|
||||
def test_측구_구조물_선_design_ids_단일_도면() -> None:
|
||||
use_project_templates(None)
|
||||
drawing = build_cross_drawing(
|
||||
_source(0.0), "d", _LINE, _DESIGN, {"ground": 1.0, "planned": 0.5}, "No.0"
|
||||
)
|
||||
ditch = [e for e in drawing["entities"] if e["layerId"] == STRUCTURE_LAYER_ID]
|
||||
assert len(ditch) == 1
|
||||
design_ids = drawing["cross_placements"][0]["design_ids"]
|
||||
assert ditch[0]["id"] in design_ids
|
||||
assert all(
|
||||
e["layerId"] in (DESIGN_LAYER_ID, STRUCTURE_LAYER_ID)
|
||||
for e in drawing["entities"]
|
||||
if e["id"] in design_ids
|
||||
)
|
||||
|
||||
|
||||
def test_측구_없으면_design_ids_설계선만() -> None:
|
||||
use_project_templates(None)
|
||||
drawing = build_cross_drawing(
|
||||
_source(0.0), "d", _LINE, None, {"ground": 1.0, "planned": 0.5}, "No.0"
|
||||
)
|
||||
ids = drawing["cross_placements"][0]["design_ids"]
|
||||
layers = {e["layerId"] for e in drawing["entities"] if e["id"] in ids}
|
||||
assert layers == {DESIGN_LAYER_ID}
|
||||
|
||||
|
||||
def test_배관_박스암거_색_따로() -> None:
|
||||
src = (ROOT / "B07_DesignDetail/B07_DesignDetail_Cross_Overlay.ts").read_text(encoding="utf-8")
|
||||
pipe = re.search(r'const PIPE_COLOR = "(#[0-9a-fA-F]{6})"', src)
|
||||
assert pipe, "PIPE_COLOR 없음"
|
||||
color = pipe.group(1).lower()
|
||||
assert color not in {STRUCTURE_COLOR, DESIGN_COLOR, GROUND_COLOR, ROCK_COLOR}
|
||||
assert color not in {
|
||||
"#8ea0b5",
|
||||
"#e8edf4",
|
||||
"#ffe066",
|
||||
"#ff4d4d",
|
||||
} # 표 선 · 글 · 값 · 구조물 평면 색
|
||||
# 박스암거 · 배수관만 pipeSvg 로 — 구조물(돌붙임 · 여울)은 그대로 노랑
|
||||
assert "appendBoxOverlay(pipeSvg," in src and "appendCulvertOverlay(\n pipeSvg," in src
|
||||
assert "appendRevetmentOverlay(svg," in src and "appendFordOverlay(svg," in src
|
||||
assert "harvest(pipeSvg, PIPE_STYLE, frame)" in src
|
||||
Reference in New Issue
Block a user