Merge remote-tracking branch 'origin/main_desktop_1' into main_laptop_1

This commit is contained in:
2026-09-04 19:14:09 +09:00
35 changed files with 727 additions and 92 deletions
+1 -1
View File
@@ -113,7 +113,7 @@ def _load_pipe_points(project_root: Path, polyline: list[list[float]]) -> list[P
물린 자리와 측점 자리가 어긋난다.
관 지점 파일에는 저장 당시 노선 지문이 함께 있다. 지문이 달라도 저장분에 좌표가 있으면
**이 계획선에 투영해 이월한다** — B04가 관 자리를 정한 선(계획노선 CSV)과 여기 계획선은
**이 계획선에 투영해 이월한다** — B04가 관 자리를 정한 선(계획노선 정본)과 여기 계획선은
같은 자리를 지나면서 연장이 다르다(실측 350.11m vs 354.83m). 그래서 지문은 거의 항상
달랐고 관이 통째로 빠졌다(2026-08-30 사용자 지적). 좌표가 없는 구 저장분만 버린다.
"""
@@ -9,10 +9,12 @@
* ========================================================================== */
import {
computeMaxScale,
lonLatToScreen,
type Normalizer,
type ViewState,
} from "../B04_PreProcess/B04_PreProcess_UI_MapRender";
import type { VWorldMeta } from "../B04_PreProcess/B04_PreProcess_Api_Fetch";
import type { DetailBasin } from "../B04_PreProcess/B04_PreProcess_Api_Fetch";
import { pointInRings } from "../B04_PreProcess/B04_PreProcess_UI_MapOverlays";
import type { createPipeEditor } from "./B05_Profile_UI_Drainage_Pipes";
@@ -29,6 +31,8 @@ export interface DrainageInteractParams {
currentView: () => ViewState;
getScale: () => number;
setScale: (value: number) => void;
/** 배율 상한을 도엽 실폭으로 계산하기 위한 메타 (2026-09-04). 없으면 종전 고정 상한. */
getMeta: () => VWorldMeta | null;
getOffset: () => { x: number; y: number };
setOffset: (x: number, y: number) => void;
scheduleDraw: () => void;
@@ -55,7 +59,10 @@ export function bindDrainageInteractions(params: DrainageInteractParams): void {
event.preventDefault();
const prevScale = params.getScale();
// 휠을 **당기면 확대**, 밀면 축소한다(2026-08-02 사용자 지시). B04 2D 지도와 같은 방향이다.
const scale = Math.min(16, Math.max(0.5, prevScale * (event.deltaY > 0 ? 1.15 : 0.87)));
// 상한은 「화면 폭 20m」로 계산한다 — B04 지도와 같은 규칙(2026-09-04 사용자 지시).
const view = currentView();
const maxScale = computeMaxScale(params.getMeta(), view.mapRect.width, view.width, 16);
const scale = Math.min(maxScale, Math.max(0.5, prevScale * (event.deltaY > 0 ? 1.15 : 0.87)));
params.setScale(scale);
// 커서 아래 지점을 고정한 채 확대/축소 (B04 지도와 동일 동작).
const ratio = scale / prevScale;
@@ -12,6 +12,7 @@ import {
} from "../B04_PreProcess/B04_PreProcess_Api_Fetch";
import {
computeMapRect,
MAP_STATION_INTERVAL_M,
createNormalizer,
prepareLayer,
prepareMetricPolyline,
@@ -200,6 +201,9 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra
function updateImageTransform(): void {
backgroundImage.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
// 크게 당기면 도엽 그림이 뭉개진다 — 흐림 보간을 끄고 픽셀을 그대로 보인다
// (2026-09-04 사용자 지시). 축척 막대가 실제 크기를 알려 준다.
backgroundImage.style.imageRendering = scale > 4 ? "pixelated" : "auto";
}
function draw(): void {
@@ -244,6 +248,7 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra
pipeEditor,
pipeColor,
markedChainage,
stationIntervalM: MAP_STATION_INTERVAL_M,
});
updateImageTransform();
}
@@ -488,6 +493,7 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra
setScale: (value) => {
scale = value;
},
getMeta: () => meta,
getOffset: () => ({ x: offsetX, y: offsetY }),
setOffset: (x, y) => {
offsetX = x;
+2 -18
View File
@@ -171,24 +171,8 @@ export function renderBasinRows(
/** 사업지 좌표계(m) → 화면 px 변환기. 흐름 화살표와 강도 색칠이 같은 식을 쓴다 —
* 둘이 어긋나면 색은 계획선 위인데 화살표만 밀린 것처럼 보인다. */
export function createMetricProjector(
meta: VWorldMeta,
view: ViewState,
): { toScreen: (x: number, y: number) => [number, number]; pxPerMeter: number } {
const spanX = meta.width_meters || 1;
const spanY = meta.height_meters || 1;
const ax = view.mapRect.width * view.scale;
const bx = view.mapRect.x * view.scale + (view.width / 2) * (1 - view.scale) + view.offsetX;
const ay = view.mapRect.height * view.scale;
const by = view.mapRect.y * view.scale + (view.height / 2) * (1 - view.scale) + view.offsetY;
return {
toScreen: (x, y) => [
((x - meta.x_min) / spanX) * ax + bx,
(1 - (y - meta.y_min) / spanY) * ay + by,
],
pxPerMeter: ax / spanX,
};
}
// 미터 좌표 → 화면 좌표 변환기는 B04 지도와 공용이다(정의처: MapRender).
export { createMetricProjector } from "../B04_PreProcess/B04_PreProcess_UI_MapRender";
/** 배관 우클릭 메뉴를 지도 뷰포트에 붙인다 — 마커 위면 삭제, 계획선 위면 추가.
@@ -22,6 +22,7 @@ import {
drawFilledRing,
drawRidgeRing,
drawRingBadge,
drawStationTicks,
drawUpstreamLines,
ringCenterOnScreen,
} from "../B04_PreProcess/B04_PreProcess_UI_MapOverlays";
@@ -64,6 +65,8 @@ export interface DrainageScene {
pipeColor: (chainage: number, position: number) => string;
/** 선택된 측점의 누가거리(m). 계획선 위 그 자리에 선택 표식을 그린다(null=없음). */
markedChainage: number | null;
/** 규칙 측점 간격(m) — 눈금·번호 표기 기준 (2026-09-04 사용자 지시). */
stationIntervalM: number;
}
export function drawDrainageScene(
@@ -182,6 +185,13 @@ export function drawDrainageScene(
context.stroke();
context.restore();
}
// 측점 눈금·번호 — 관 마커 위, 유역 번호 아래 (2026-09-04 사용자 지시). B04 지도와 공용.
drawStationTicks(context, scene.strengthSamples, {
intervalM: scene.stationIntervalM,
pxPerMeter: projector.pxPerMeter,
toScreen: projector.toScreen,
avoidChainages: scene.pipeEditor.chainages(),
});
// 유역 번호 — 무엇에도 가리지 않게 맨 마지막.
drawBadges(context, badges);
}