From 4793eb41300db370dc19652766210decc3f5f047 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 12 Sep 2026 15:09:09 +0900 Subject: [PATCH] =?UTF-8?q?feat(B05):=20=EA=B3=84=ED=9A=8D=EB=85=B8?= =?UTF-8?q?=EC=84=A0=20=ED=8E=B8=EC=A7=91=20=ED=99=94=EB=A9=B4=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC=EC=99=80=20=EC=A7=80=EB=8F=84=20=ED=9A=8C=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 조작 설명을 지도 좌상단 2열 오버레이로, 상태·범례를 좌하단 오버레이로 (계획서 0-9 ⑩⑫) - 단추를 제목행 오른쪽으로 옮기고 공용 `.ui-btn` 규격을 씀, 하단 정보행 삭제 (⑪⑬) - LAS 등고선을 도엽과 같은 5m 단위로 그림 (⑭) - 바탕이 LAS 면 세류선도 등고선 범위 안쪽만 그림 (⑮) - 지도 오른쪽 위 반시계·시계 단추로 15°씩 그림 전체 회전, 집기도 따라감 (⑯) - R·L 하한을 5m 로 채움. 다만 L 하한은 칸 입력만 막음 — 기하에 걸면 거의 곧은 자리에서 R 이 부풀어 아무것도 안 고쳤는데 노선이 바뀜 (⑰) Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_012jsXWphgRUHAG2mFupSKPX --- B04_PreProcess/B04_PreProcess_UI_MapRender.ts | 27 ++++++ B05_Profile/B05_Profile_UI_RouteEdit.ts | 84 ++++++++++------- .../B05_Profile_UI_RouteEdit_Contour.ts | 16 +++- .../B05_Profile_UI_RouteEdit_CurveBar.ts | 1 + B05_Profile/B05_Profile_UI_RouteEdit_Edits.ts | 42 ++++----- B05_Profile/B05_Profile_UI_RouteEdit_Input.ts | 17 ++-- .../B05_Profile_UI_RouteEdit_Render.ts | 24 +++++ .../B05_Profile_UI_RouteEdit_Rotate.ts | 71 +++++++++++++++ .../B05_Profile_UI_Style_RouteEdit.css | 89 ++++++++++++------- config/config_system_design.py | 24 ++--- resources/tester/test_plan_curve_limits.py | 24 ++--- 11 files changed, 301 insertions(+), 118 deletions(-) create mode 100644 B05_Profile/B05_Profile_UI_RouteEdit_Rotate.ts diff --git a/B04_PreProcess/B04_PreProcess_UI_MapRender.ts b/B04_PreProcess/B04_PreProcess_UI_MapRender.ts index 00aa2b95..7921d46e 100644 --- a/B04_PreProcess/B04_PreProcess_UI_MapRender.ts +++ b/B04_PreProcess/B04_PreProcess_UI_MapRender.ts @@ -438,6 +438,33 @@ function isVisible(feature: PreparedFeature, affine: Affine, view: ViewState): b ); } +/** 레이어가 차지하는 **화면 사각형**(px). 피처가 없으면 null. + * + * LAS 등고선처럼 도엽보다 좁은 자료 위에 다른 레이어를 겹칠 때, 그 자료가 있는 데까지만 + * 그리려고 쓴다(계획서 0-9 ⑮ — 세류선이 등고선 밖까지 뻗던 자리). */ +export function layerScreenBounds( + layer: PreparedLayer, + view: ViewState, +): { x: number; y: number; width: number; height: number } | null { + if (layer.features.length === 0) return null; + const affine = affineOf(view); + let minX = Infinity; + let minY = Infinity; + let maxX = -Infinity; + let maxY = -Infinity; + for (const feature of layer.features) { + minX = Math.min(minX, feature.minX); + minY = Math.min(minY, feature.minY); + maxX = Math.max(maxX, feature.maxX); + maxY = Math.max(maxY, feature.maxY); + } + const x0 = minX * affine.ax + affine.bx; + const x1 = maxX * affine.ax + affine.bx; + const y0 = minY * affine.ay + affine.by; + const y1 = maxY * affine.ay + affine.by; + return { x: x0, y: y0, width: x1 - x0, height: y1 - y0 }; +} + /** 등고선을 몇 m 마다 낼지 고를 때 훑는 배수. 성긴 쪽으로 한 칸씩 물러난다. */ const LEVEL_STEP_MULTIPLES = [1, 2, 5, 10, 20, 50, 100]; /** 한 화면에 둘 등고선 가닥 수의 어림 상한 — 이보다 많으면 한 칸 성글게 간다. */ diff --git a/B05_Profile/B05_Profile_UI_RouteEdit.ts b/B05_Profile/B05_Profile_UI_RouteEdit.ts index 99c76a89..dd517a27 100644 --- a/B05_Profile/B05_Profile_UI_RouteEdit.ts +++ b/B05_Profile/B05_Profile_UI_RouteEdit.ts @@ -45,6 +45,7 @@ import { stationAtScreen, } from "./B05_Profile_UI_RouteEdit_Input"; import { createCrossPreview } from "./B05_Profile_UI_RouteEdit_Cross"; +import { createMapRotation } from "./B05_Profile_UI_RouteEdit_Rotate"; import { createMeasureTool } from "./B05_Profile_UI_RouteEdit_Measure"; import { createCurveBar } from "./B05_Profile_UI_RouteEdit_CurveBar"; import { @@ -98,30 +99,40 @@ export async function openRouteEditModal(