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:
@@ -13,11 +13,44 @@ import type {
|
||||
GeoJsonCollection,
|
||||
GeoJsonGeometry,
|
||||
Normalizer,
|
||||
PartLod,
|
||||
PreparedFeature,
|
||||
PreparedLayer,
|
||||
PreparedPart,
|
||||
} from "../B04_PreProcess_UI_MapRender";
|
||||
|
||||
/** 줌 단계 무게(정규화 좌표 · 큰 → 작은 · 4 배 간격) — 화면 1 폭 ≈ 1,400 px 이면 다 줌아웃 ~ 2,000 배. */
|
||||
const LOD_THRESHOLDS = [4 ** -5, 4 ** -6, 4 ** -7, 4 ** -8, 4 ** -9, 4 ** -10];
|
||||
/** 이보다 짧은 조각은 색인 없이 전부 훑음(훑기가 이미 짧음). */
|
||||
const LOD_MIN_VERTICES = 64;
|
||||
|
||||
/** 조각 하나의 줌 단계 색인. 짧거나 무게가 없으면 undefined. */
|
||||
export function buildPartLod(weights: Float64Array | null): PartLod | undefined {
|
||||
if (!weights || weights.length < LOD_MIN_VERTICES) return undefined;
|
||||
const lists = LOD_THRESHOLDS.map((threshold) => {
|
||||
const kept: number[] = [];
|
||||
for (let v = 0; v < weights.length; v += 1) if (weights[v] >= threshold) kept.push(v);
|
||||
return Uint32Array.from(kept);
|
||||
});
|
||||
return { thresholds: LOD_THRESHOLDS, lists };
|
||||
}
|
||||
|
||||
/** 허용 오차에 맞는 가장 성긴 단 — 「무게 ≥ 오차」 정점을 모두 담음. 맞는 단이 없으면 null(전부 훑음). */
|
||||
export function pickLodList(lod: PartLod, tolerance: number): Uint32Array | null {
|
||||
for (let k = 0; k < lod.thresholds.length; k += 1)
|
||||
if (lod.thresholds[k] <= tolerance) return lod.lists[k];
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 레이어 선 조각마다 줌 단계 색인을 붙임(제자리 · 582 — 지금 D03 만 부름). */
|
||||
export function indexLayerLod(layer: PreparedLayer): PreparedLayer {
|
||||
for (const feature of layer.features) {
|
||||
if (feature.kind !== "line") continue;
|
||||
for (const part of feature.parts) part.lod = buildPartLod(part.weights);
|
||||
}
|
||||
return layer;
|
||||
}
|
||||
|
||||
function isPoint(value: unknown): value is [number, number] {
|
||||
return Array.isArray(value) && typeof value[0] === "number" && typeof value[1] === "number";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user