Merge remote-tracking branch 'origin/main_desktop_1' into main_laptop_1
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user