perf(전처리 화면): 343-3 B04 다시 열기 받는 양 — 보관함 저장 실패 고침 · 점군 고정 표본 이진 · 꺼진 층은 켤 때 · 남은 층 ETag · 등고선 주소 한 벌
- b_asset_cache — 쓰기 끝 = 트랜잭션 완료(용량 초과 취소 잡음) · 실패 한 줄 경고(까닭당 한 번) · onblocked · onversionchange · 열기 실패 null 안 기억 · 지우기는 색인 열쇠 · 앞머리 범위(값 안 읽음)
- 점군 미리보기 — 전처리 때 고정 표본 이진(preview_points_{필터}.bin · 원천 지문 같으면 건너뜀) · GET point-cloud/binary(ETag) · 화면은 fetchCachedBytes(IndexedDB) + decodePointPreview(py 짝)
- B04 지도 — 켜진 층만 처음에 받음 · 꺼진 층은 켤 때 · 같은 층 겹쳐 받기 막음
- geojson(지적도 · 행정구역 · 등고선) 파일 그대로 cached_file_response(ETag) · 등고선 단순화본은 원본이 새로우면 다시 만듦
- 등고선 주소 contourAssetUrl 하나(B04 · 미리 받기) — B05 두 곳은 sub5 몫
- 시험 test_343_3_browser_cache 13건 + helper_343_3_asset_cache.cjs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
API_TIMEOUT_MS,
|
||||
} from "@config/config_frontend";
|
||||
import { showToast } from "@ui/ui_template_elements";
|
||||
import { fetchCachedBytes } from "../A00_Common/b_asset_cache";
|
||||
import type { GroupItems, SummaryItem } from "../common_util/common_util_summary_item";
|
||||
|
||||
/** 지표면 분석 실행 요청 (SurfaceAnalyzeRequest) */
|
||||
@@ -244,17 +245,49 @@ export async function listSurfaceInputFiles(
|
||||
});
|
||||
}
|
||||
|
||||
/** 점군 미리보기 고정 표본 이진(IndexedDB 보관 · ETag) — 다시 열 때 받지 않는다. */
|
||||
export async function fetchSurfacePointCloud(
|
||||
projectId: string,
|
||||
filter?: string,
|
||||
): Promise<SurfacePointCloudSampleResponse> {
|
||||
const query = filter ? `?filter=${encodeURIComponent(filter)}` : "";
|
||||
return requestJson<SurfacePointCloudSampleResponse>(
|
||||
`/projects/${projectId}/surface/point-cloud${query}`,
|
||||
{
|
||||
method: "GET",
|
||||
},
|
||||
const bytes = await fetchCachedBytes(
|
||||
projectId,
|
||||
`${API_BASE_URL}/projects/${projectId}/surface/point-cloud/binary${query}`,
|
||||
);
|
||||
return { status: "success", project_id: projectId, ...decodePointPreview(bytes) };
|
||||
}
|
||||
|
||||
/**
|
||||
* 점군 미리보기 이진 풀기 — 짝 = `B04_PreProcess_Engine_PointPreview.py` `ensure_point_preview`.
|
||||
* [머리 길이 u32][머리 JSON][4 배수 채움][xyz f32 × 3n][rgb u16 × 3n].
|
||||
*/
|
||||
export function decodePointPreview(
|
||||
bytes: ArrayBuffer,
|
||||
): Omit<SurfacePointCloudSampleResponse, "status" | "project_id"> {
|
||||
const headLength = new DataView(bytes).getUint32(0, true);
|
||||
const head = JSON.parse(new TextDecoder().decode(new Uint8Array(bytes, 4, headLength))) as {
|
||||
point_count: number;
|
||||
sampled_count: number;
|
||||
bounds: SurfaceBounds;
|
||||
has_rgb: boolean;
|
||||
};
|
||||
const count = head.sampled_count;
|
||||
const offset = Math.ceil((4 + headLength) / 4) * 4;
|
||||
const xyz = new Float32Array(bytes, offset, count * 3);
|
||||
const points: [number, number, number][] = new Array(count);
|
||||
for (let index = 0; index < count; index += 1) {
|
||||
points[index] = [xyz[index * 3], xyz[index * 3 + 1], xyz[index * 3 + 2]];
|
||||
}
|
||||
let rgb: [number, number, number][] | undefined;
|
||||
if (head.has_rgb) {
|
||||
const colors = new Uint16Array(bytes, offset + xyz.byteLength, count * 3);
|
||||
rgb = new Array(count);
|
||||
for (let index = 0; index < count; index += 1) {
|
||||
rgb[index] = [colors[index * 3], colors[index * 3 + 1], colors[index * 3 + 2]];
|
||||
}
|
||||
}
|
||||
return { point_count: head.point_count, sampled_count: count, bounds: head.bounds, points, rgb };
|
||||
}
|
||||
|
||||
/** 확정 지표면 구성 + 지형 가장자리만 조회한다(수 KB).
|
||||
|
||||
Reference in New Issue
Block a user