fix(B04·B05): 지도 경위도 겹 · 위성 그림을 TM 겹 자리로 맞춤 (PLAN 589-1 · 요구 447 · 448)
- 서버 위성 메타 응답에 그림 상자 9×9 TM 격자(tm_grid · pyproj · 응답 때 셈 · 귀퉁이 1 cm 넘게 다르면 안 줌) - 공용 createTmNormalizer(고를 칸 toNorm · 격자 쌍선형) · normOfLonLat · imageScreenMatrix · placeMapImage - B04 하단 지도 · B05 배수유역도 · B05 평면 노선 편집이 TM 자리로 · 위성 그림 = 화면 가운데 1차 행렬(contain 뺌) - Watershed 손 베낌 식 넷 · 줌아웃 한계 = 공용 식 · D03 길(createNormalizer) 바뀜 없음 · TM 길 손 안 댐 - 지킴 시험 test_589_tm_grid(Bessel · GRS80 · 격자 = pyproj 0.02 m · 그림 행렬 0.5 px · 옛 꼴 어긋남) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -34,9 +34,10 @@ import {
|
||||
computeRouteView,
|
||||
createMetricProjector,
|
||||
MAP_STATION_INTERVAL_M,
|
||||
createNormalizer,
|
||||
createTmNormalizer,
|
||||
drawPreparedLabels,
|
||||
drawPreparedLayer,
|
||||
placeMapImage,
|
||||
routeLineColor,
|
||||
ROUTE_LINE_WIDTH,
|
||||
type MapRect,
|
||||
@@ -108,6 +109,7 @@ export function createSurfaceMapViewer(): SurfaceMapViewer {
|
||||
image.className = "b04-map__image";
|
||||
image.alt = L("B04_Surface_Map_ImageAlt");
|
||||
image.draggable = false;
|
||||
image.addEventListener("load", () => scheduleDraw());
|
||||
backgroundImages.set(layer, image);
|
||||
});
|
||||
const canvas = document.createElement("canvas");
|
||||
@@ -308,13 +310,9 @@ export function createSurfaceMapViewer(): SurfaceMapViewer {
|
||||
// 강도 색띠 범례도 같은 자리에 얹는다(CSS가 우측 세로로 세운다).
|
||||
viewport.append(detailBasins.menuElement, flowStrength.legendElement);
|
||||
|
||||
function updateImageTransform(): void {
|
||||
backgroundImages.forEach((image) => {
|
||||
image.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
|
||||
// 크게 당기면 배경 그림이 뭉개진다 — 흐림 보간을 끄고 픽셀을 그대로 보인다
|
||||
// (2026-09-04 사용자 지시). 실제 크기는 축척 막대로 읽는다.
|
||||
image.style.imageRendering = scale > 4 ? "pixelated" : "auto";
|
||||
});
|
||||
/** 배경 그림을 TM 겹 자리로 놓음(589-1 · 공용 `placeMapImage`). */
|
||||
function updateImageTransform(view: ViewState): void {
|
||||
backgroundImages.forEach((image) => placeMapImage(image, meta, normalizer, view));
|
||||
}
|
||||
|
||||
function syncLayerVisibility(): void {
|
||||
@@ -346,7 +344,6 @@ export function createSurfaceMapViewer(): SurfaceMapViewer {
|
||||
|
||||
function resetView(): void {
|
||||
fitRouteView();
|
||||
updateImageTransform();
|
||||
scheduleDraw();
|
||||
}
|
||||
|
||||
@@ -432,7 +429,7 @@ export function createSurfaceMapViewer(): SurfaceMapViewer {
|
||||
detailBasins.draw(context, normalizer, view);
|
||||
// 유입 집중점(집중유역)은 맨 마지막 — 켰을 때 무엇에도 가리지 않아야 고를 수 있다.
|
||||
flowStrength.drawTop(context, normalizer, view);
|
||||
updateImageTransform();
|
||||
updateImageTransform(view);
|
||||
drawScaleBar(mapRect);
|
||||
}
|
||||
|
||||
@@ -489,7 +486,7 @@ export function createSurfaceMapViewer(): SurfaceMapViewer {
|
||||
if (sequence !== loadSequence) return;
|
||||
meta = nextMeta;
|
||||
// 좌표 변환은 여기서 1회만 수행하고, 이후 프레임은 사전 투영 결과만 사용한다.
|
||||
normalizer = createNormalizer(nextMeta);
|
||||
normalizer = createTmNormalizer(nextMeta);
|
||||
routeLayer =
|
||||
planned.points.length > 1 ? prepareMetricPolyline(planned.points, nextMeta) : null;
|
||||
routePoints = planned.points;
|
||||
|
||||
Reference in New Issue
Block a user