perf(D03): 노선분석 평면 두 장 캔버스 · 한 화면 한 번 그리기 · 등고선 줌 단계 색인 · 글 폭 기억 — 그림 그대로 (PLAN 582-0 · 582-1 · 요구 440-9 · 441)

- D03 평면 = 바탕(위성 · 바탕 겹 다섯) / 위(그은 선 · 재기) 두 장 · 마우스 움직임 · 누름 = 위만 · 화면 바뀜 = 둘 다 · rAF 한 화면 한 번
- PlanMap.redraw = 위 겹만 · redrawBase = 바탕까지(겹 켬끔 · 받음)
- 공용 그리기에 선택 칸만 더함 — 조각 색인(part.lod · indexLayerLod 를 부른 레이어만) · 글 폭 기억(widths 인자) · B04 · B05 는 안 켬
- 한 판 한 번 긋기(d)는 뺌 — 반투명 선 겹침 색이 바뀌고(픽셀 14만 차) 래스터가 더 느림(36 → 60 ms)
- 지킴 시험 test_582_contour_lod — 색인 그린 명령 = 지금 명령(27 줌 · 자리 · 닫힌 고리 · 짧은 조각) · 글 폭 기억 같은 글

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 14:41:59 +09:00
co-authored by Claude Opus 5.5
parent c4b37023c7
commit 5e906ceb44
7 changed files with 420 additions and 29 deletions
+16 -4
View File
@@ -7,6 +7,7 @@
* 처음 켬 = 위성 · 등고선 · 세류 · 고른 값 = 화면 취향(`aislo:pref:d03.layers`) 기억.
* 받기 = 켤 때만(한 번 받으면 다시 안 받음) · 지형을 안 받았으면 단추를 막음.
* 그리기 차례(아래 → 위) = 위성(`scene.image`) → 급경사 → 지적 → 등고선 → 도로 → 세류 → 그은 선.
* 겹 다섯 = 바탕 캔버스(`base` · 582) · 등고선 = 줌 단계 색인 · 글 폭 기억.
* ========================================================================== */
import { createIconButton } from "@ui/ui_template_button";
@@ -30,7 +31,10 @@ import {
type GeoJsonCollection,
type PreparedLayer,
} from "../B04_PreProcess/B04_PreProcess_UI_MapRender";
import { prepareLayer } from "../B04_PreProcess/logic/B04_PreProcess_UI_MapRender_Prepare";
import {
indexLayerLod,
prepareLayer,
} from "../B04_PreProcess/logic/B04_PreProcess_UI_MapRender_Prepare";
import {
fetchPlanCadastral,
fetchPlanRaster,
@@ -159,7 +163,7 @@ export function createPlanLayers(opts: {
void ensure(key);
showSatellite();
sync();
map.redraw();
map.redrawBase();
}
function showSatellite(): void {
@@ -178,7 +182,7 @@ export function createPlanLayers(opts: {
if (meta !== at) return;
showSatellite();
sync();
map.redraw();
map.redrawBase();
})
.catch((error: unknown) => {
const text = error instanceof Error ? error.message : String(error);
@@ -213,7 +217,7 @@ export function createPlanLayers(opts: {
"route",
bbox.join(","),
);
data.contour = prepare(collection, ["등고수치"]);
data.contour = indexLayerLod(prepare(collection, ["등고수치"]));
} else if (key === "stream") {
const collection = await fetchCachedSheetLayer<GeoJsonCollection>(
projectId,
@@ -258,8 +262,11 @@ export function createPlanLayers(opts: {
drawPreparedLayer(context, layer, map.view, "dot", everyM);
};
/** 등고 글 폭 기억(글꼴 하나 · 582). */
const labelWidths = new Map<string, number>();
const layers: PlanMapLayer[] = [
{
base: true,
draw: (context, map) => {
const slope = on.slope && data.slope;
if (!slope) return;
@@ -271,6 +278,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.cadastral || !data.cadastral) return;
context.globalAlpha = 0.8;
@@ -278,6 +286,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
const contour = on.contour && data.contour;
if (!contour) return;
@@ -297,10 +306,12 @@ export function createPlanLayers(opts: {
25,
map.uprightRad,
"rgba(0, 0, 0, 0.6)",
labelWidths,
);
},
},
{
base: true,
draw: (context, map) => {
if (!on.road || !data.road) return;
stroke(context, map, data.road, "rgba(0, 0, 0, 0.55)", 3.2);
@@ -308,6 +319,7 @@ export function createPlanLayers(opts: {
},
},
{
base: true,
draw: (context, map) => {
if (!on.stream || !data.stream) return;
const color = themeColor("--draw-map-stream", "#38bdf8");