From 1c1eb71b92195b087957e2e1f6ece43ed24ef044 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 7 Oct 2026 07:53:41 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix(B06):=20=ED=9A=A1=EB=8B=A8=EB=8F=84=20?= =?UTF-8?q?=EA=B4=80=20=EA=B0=80=EC=9A=B4=EB=8D=B0=20=EA=B4=80=20=ED=84=B0?= =?UTF-8?q?=ED=8C=8C=EA=B8=B0=20=EC=A0=90=EC=84=A0=20=EC=82=AD=EC=A0=9C(73?= =?UTF-8?q?-6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 정체 = 관 중심에 수직으로 그리던 관 터파기 사각 파선(#8a5c3c 황갈 · 4 3) - 그리기 호출 · 안 쓰는 appendPipeTrench 삭제 (관 터파기 폭 계산 · 수량 그대로 · 벽 터파기 선 그대로) - 검증 프로젝트 66측점 · 밝음 · 어두움 테마 둘 다 황색 계열 점선 0 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7 --- B06_Section/B06_Section_UI_Cross_Culvert.ts | 26 +----------- .../B06_Section_UI_Cross_Excavation.ts | 41 +------------------ 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/B06_Section/B06_Section_UI_Cross_Culvert.ts b/B06_Section/B06_Section_UI_Cross_Culvert.ts index ff2a572bc..06ac4eb63 100644 --- a/B06_Section/B06_Section_UI_Cross_Culvert.ts +++ b/B06_Section/B06_Section_UI_Cross_Culvert.ts @@ -21,11 +21,7 @@ import type { PipeEnd, WallLayout, } from "./B06_Section_UI_Cross_Culvert_Geom"; -import { - appendPipeTrench, - appendWallTrench, - foundationChoice, -} from "./B06_Section_UI_Cross_Excavation"; +import { appendWallTrench, foundationChoice } from "./B06_Section_UI_Cross_Excavation"; import { appendWallHatch } from "./B06_Section_UI_Cross_Wall_Hatch"; // 기하 계산 진입점과 공개 상수·타입은 여기서 재수출한다 — B05(최소 토피)와 횡단 뷰가 @@ -280,26 +276,6 @@ export function appendCulvertOverlay( const inletFinal = pushOut(pipeCorners.inlet, -1); const outletFinal = pushOut(pipeCorners.outlet, 1); - // 관 터파기 — 표값 폭으로 관 위 지반선에서 관 바닥까지 수직(KCS 44 40 10 그림 3.2-1). - if (!hidePipe) { - const invert = Math.min( - pipeCorners.inlet.bottom.elevation, - pipeCorners.outlet.bottom.elevation, - ); - const centerOffset = (pipeCorners.inlet.bottom.offset + pipeCorners.outlet.bottom.offset) / 2; - appendPipeTrench( - layer, - { - centerOffsetM: centerOffset, - invertM: invert, - topM: invert + diameter + culvert.min_cover_m, - diameterMm: Math.round(diameter * 1000), - }, - x, - toDisplayY, - ); - } - const kindLabel = culvert.pipe_kind ? `${culvert.pipe_kind} ` : ""; const wallThickness = pipeWallThicknessM(culvert.pipe_kind, diameter); const tip = diff --git a/B06_Section/B06_Section_UI_Cross_Excavation.ts b/B06_Section/B06_Section_UI_Cross_Excavation.ts index d7d1120ac..a432f412d 100644 --- a/B06_Section/B06_Section_UI_Cross_Excavation.ts +++ b/B06_Section/B06_Section_UI_Cross_Excavation.ts @@ -1,6 +1,6 @@ /* ============================================================================= * B06_Section_UI_Cross_Excavation.ts - * 횡단도에 **터파기 선**을 얹는다 — 관·벽 두 갈래(2026-09-09 사용자 확정 ④). + * 횡단도에 **벽 터파기 선**을 얹는다 — 관 터파기 선은 그리지 않음(사용자 10-7). * * 왜 있나 — 「터파기가 현재 횡단도에서 표현이 안 된다」가 사용자 지적이었다. 수량을 * 세기 전에 **도면에 그것이 보여야** 한다. @@ -13,14 +13,12 @@ * ========================================================================== */ import { - BASIS_PIPE, BASIS_WALL, WALL_BLINDING_DEPTH_M, WALL_BLINDING_WIDTH_M, WALL_FOUNDATION_DEPTH_M, WALL_FOUNDATION_WIDTH_M, WALL_TRENCH_CLEARANCE_M, - pipeTrenchWidthM, } from "@util/common_util_excavation"; import type { WallLayout } from "./B06_Section_UI_Cross_Culvert_Types"; @@ -44,43 +42,6 @@ function trenchPath(layer: SVGElement, corners: Array<[number, number]>, tooltip layer.append(line); } -/** - * 관 터파기 — **표값 폭**으로 관 위 지반선에서 관 바닥까지 수직으로 판다. - * 표에 없는 관경이면 **아무것도 그리지 않는다**(폭을 지어내지 않는다). - */ -export function appendPipeTrench( - layer: SVGElement, - input: { - /** 관 중심 offset(m). */ - centerOffsetM: number; - /** 관 바닥(invert) 표고. */ - invertM: number; - /** 터파기 윗면 표고 — 관 위 지반(또는 노면)선. */ - topM: number; - diameterMm: number | null | undefined; - }, - x: (offset: number) => number, - toDisplayY: (elevation: number) => number, -): number | null { - const width = pipeTrenchWidthM(input.diameterMm); - if (width === null || !(input.topM > input.invertM)) return null; - const half = width / 2; - const left = input.centerOffsetM - half; - const right = input.centerOffsetM + half; - trenchPath( - layer, - [ - [x(left), toDisplayY(input.topM)], - [x(left), toDisplayY(input.invertM)], - [x(right), toDisplayY(input.invertM)], - [x(right), toDisplayY(input.topM)], - ], - `관 터파기 폭 ${width.toFixed(2)}m · 깊이 ${(input.topM - input.invertM).toFixed(2)}m\n` + - `Φ${Math.round(Number(input.diameterMm))}㎜ — ${BASIS_PIPE}`, - ); - return width; -} - /** * 벽 터파기 — 벽 바닥선 아래로 **수직**. 폭은 바닥 폭 + 여유 0.2, 깊이는 기초 몫. * `foundation` 이 비어 있으면 **그리지 않는다** — 사용자가 고르기 전에는 근거가 없다. From 5e3ad4524895d532017022bb2d56262fb9f8da9d Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 7 Oct 2026 08:04:59 +0900 Subject: [PATCH 2/2] =?UTF-8?q?revert(B06):=20=ED=9A=A1=EB=8B=A8=EB=8F=84?= =?UTF-8?q?=20=EC=95=94=20=EA=B2=BD=EA=B3=84=EC=84=A0=20=EB=90=98=EC=82=B4?= =?UTF-8?q?=EB=A6=BC=20=E2=80=94=20bd63f48b9=20=EB=90=98=EB=8F=8C=EB=A6=BC?= =?UTF-8?q?(=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=A0=95=EC=A0=95=2010-7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 암 경계선 그리기 · 부르기 · 스타일 되살림(58장 삭제 실수) - 73-6 노란 점선 정체 = 관 터파기 사각 파선(1c1eb71b9 에서 삭제 · 그대로) - 검증 프로젝트 암 경계선 65측점 다시 보임 · 관 터파기 점선 0 · 관 띠 11측점 그대로 This reverts commit bd63f48b9eecac08d2647bb48f8c0acb958cd6fc. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7 --- B06_Section/B06_Section_UI_Cross_Design.ts | 5 +++- .../B06_Section_UI_Cross_Design_Surface.ts | 27 +++++++++++++++++++ B06_Section/B06_Section_UI_Cross_View.ts | 11 ++++++++ .../B06_Section_UI_Style_Cross_Areas.css | 17 ++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/B06_Section/B06_Section_UI_Cross_Design.ts b/B06_Section/B06_Section_UI_Cross_Design.ts index 900f9c2c5..47e973173 100644 --- a/B06_Section/B06_Section_UI_Cross_Design.ts +++ b/B06_Section/B06_Section_UI_Cross_Design.ts @@ -24,7 +24,10 @@ import type { SectionMode, SectionSample, } from "./B06_Section_Api_Fetch"; -export { appendPavementOverlay } from "./B06_Section_UI_Cross_Design_Surface"; +export { + appendPavementOverlay, + appendRockBoundaryOverlay, +} from "./B06_Section_UI_Cross_Design_Surface"; const SVG_NS = "http://www.w3.org/2000/svg"; diff --git a/B06_Section/B06_Section_UI_Cross_Design_Surface.ts b/B06_Section/B06_Section_UI_Cross_Design_Surface.ts index cf6419403..b35b73912 100644 --- a/B06_Section/B06_Section_UI_Cross_Design_Surface.ts +++ b/B06_Section/B06_Section_UI_Cross_Design_Surface.ts @@ -2,6 +2,33 @@ import type { CrossDesign } from "./B06_Section_Api_Fetch"; const SVG_NS = "http://www.w3.org/2000/svg"; +export function appendRockBoundaryOverlay( + svg: SVGElement, + samples: Array<{ offset_m?: number; elevation_m?: number | null; valid: boolean }>, + offsetM: number, + x: (offset: number) => number, + y: (elevation: number) => number, +): void { + const segments: string[][] = []; + let current: string[] = []; + for (const sample of samples) { + const elevation = sample.elevation_m; + if (sample.valid === false || elevation === null || !Number.isFinite(elevation ?? NaN)) { + if (current.length > 1) segments.push(current); + current = []; + continue; + } + current.push(`${x(sample.offset_m ?? 0)},${y((elevation as number) + offsetM)}`); + } + if (current.length > 1) segments.push(current); + for (const points of segments) { + const polyline = document.createElementNS(SVG_NS, "polyline"); + polyline.setAttribute("points", points.join(" ")); + polyline.setAttribute("class", "b06-chart__rock-boundary"); + svg.append(polyline); + } +} + export function appendPavementOverlay( svg: SVGElement, design: CrossDesign, diff --git a/B06_Section/B06_Section_UI_Cross_View.ts b/B06_Section/B06_Section_UI_Cross_View.ts index 85343d197..8ae48e147 100644 --- a/B06_Section/B06_Section_UI_Cross_View.ts +++ b/B06_Section/B06_Section_UI_Cross_View.ts @@ -26,6 +26,7 @@ import { appendRevetmentOverlay, computeRevetmentLayout } from "./B06_Section_UI import { appendCrossDesignOverlay, appendPavementOverlay, + appendRockBoundaryOverlay, type RockBoundaryControl, } from "./B06_Section_UI_Cross_Design"; import { appendCardFooter, appendCardHeader } from "./B06_Section_UI_Cross_Card_Chrome"; @@ -488,6 +489,16 @@ export function createCrossSectionCard( // 사토장(유용토운반작업장) — 교본 6장 3절이 횡단도 표시를 요구한다. 값은 설계 결과에서 // 그대로 오고 여기서 다시 세지 않는다. 선 종류는 터파기 파선과 갈라 둔다. appendSpoilFillOverlay(plotLayer, section.design, x, toDisplayY); + // 암 경계선 = 지면선 복사 + 오프셋(계획선 기준 아님). + if (rockBoundary && section.design.geometry_preset === "rock") { + appendRockBoundaryOverlay( + plotLayer, + drawSamples, + rockBoundary.offsetFor(section), + x, + toDisplayY, + ); + } // 배수관 세트 — 조정창이 쓸 카드 상태를 받아 둔다(2026-08-19) · 링크 카드도 채운다(2026-08-24). culvertInletIsBasin = !!culvertLayout?.basin; culvertHiddenPipe = culvertLayout?.culvert.hidden_pipe === true; diff --git a/B06_Section/B06_Section_UI_Style_Cross_Areas.css b/B06_Section/B06_Section_UI_Style_Cross_Areas.css index 4e6925180..146e3a085 100644 --- a/B06_Section/B06_Section_UI_Style_Cross_Areas.css +++ b/B06_Section/B06_Section_UI_Style_Cross_Areas.css @@ -168,6 +168,16 @@ pointer-events: none; } +/* 암 경계선(설계선 복사 + 오프셋): 리핑암·발파암 구간 점선 */ +.b06-chart__rock-boundary { + fill: none; + stroke: var(--color-warning); + stroke-width: 1.6; + stroke-dasharray: 6 4; + stroke-linejoin: round; + opacity: 0.9; +} + /* 포장층 박스: 노면 양 끝점 기준 두께만큼 하향 채움 */ .b06-chart__pavement { fill: color-mix(in srgb, var(--color-text-secondary) 30%, transparent); @@ -291,6 +301,13 @@ fill: var(--color-text-secondary); } +/* 유입 보호공 공간 확보 절토선 — 말단에서 표준단면 절토경사로 지반까지 */ +.b06-chart__culvert-cut { + stroke: var(--color-warning); + stroke-width: 1.4; + stroke-dasharray: 5 3; +} + /* 기슭막이 돌 해칭 — 기운 띠 안에 한 줄로 쌓인 큰 돌(실무 도면 형상) */ .b06-chart__culvert-stone { fill: none;