cesium-forest-streaming
v0.1.0
Published
Procedural forest streaming layer for CesiumJS — samples trees from forest-type MVT polygons on the fly (i3dm replacement, HLOD tile selection, GPU-instanced GLB rendering)
Maintainers
Readme
cesium-forest-streaming
임상도(수치 산림 지도) 폴리곤 MVT 타일로부터 나무를 실시간 절차 생성하여 CesiumJS 위에 스트리밍하는 라이브러리입니다. 사전 제작된 i3dm 타일셋을 대체하는 것이 목표로, 서버에는 폴리곤 벡터 타일만 있으면 됩니다.
- 3D Tiles식 HLOD 타일 선택: 화면공간오차(SSE) 기준 쿼드트리 refine — 근거리는 fine, 원거리는 coarse 타일이 한 화면에 공존, 무공백 타일 교체
- 결정적 샘플링: 전역 그리드 기반이라 타일 경계 seam 없음, 같은 지역은 항상 같은 나무(위치·수종·크기·방향) — Web Worker 풀에서 수행
- GPU 인스턴싱: GLB를 런타임에
EXT_mesh_gpu_instancing으로 재작성, draw call은 타일×수종 수 (나무 100만 그루 기본 상한) - LOD 렌더러: 원거리 Point / 중거리 Billboard / 근거리 GLB 자동 전환
- Terrain: quantized-mesh 지형 위 나무 배치(타일 레벨 연동 샘플링)
요구 사항
- CesiumJS ≥ 1.120 (peer dependency)
- MVT 타일 서버 URL — 임상 폴리곤을 서빙하는
{z}/{x}/{y}XYZ 엔드포인트 (예: Martin, pg_tileserv, tegola...). 서버가 없다면 server/에 PostGIS + Martin 기본 구축이 준비되어 있습니다 (GPKG 넣고docker compose up).
설치
npm install cesium-forest-streaming cesiumQuick Start
import { ForestLayer } from 'cesium-forest-streaming';
const layer = new ForestLayer({
viewer, // Cesium.Viewer
url: 'https://your-martin/forest/{z}/{x}/{y}', // MVT 타일 URL 템플릿
adapter: { // 속성 → 표준 필드 매핑
forestType: (p) => ({ 1: 'conifer', 2: 'broadleaf', 3: 'mixed' })[p.frtp_cd] ?? 'unknown',
averageHeight: (p) => Number(p.height) || 10, // 평균 수고(m)
density: (p) => ({ A: 0.3, B: 0.6, C: 1.0 })[p.dnst_cd] ?? 0.5, // 0~1
},
models: { // 수종별 GLB (1m 정규화 권장)
conifer: [{ url: '/models/needle-tree-1m.glb', referenceHeight: 1 }],
broadleaf: [{ url: '/models/broad-tree-1m.glb', referenceHeight: 1 }],
},
renderer: 'auto', // 'model' | 'billboard' | 'point' | 'auto'
}).add();주요 옵션
| 옵션 | 기본값 | 설명 |
| --- | --- | --- |
| minLevel / maxLevel | 12 / 16 | 스트리밍 타일 레벨 범위 (minLevel 미만 뷰에서는 꺼짐) |
| maxTiles | 32 | 뷰당 타일 예산 (HLOD refine/eviction의 상한) |
| maximumTreeCount | 1,000,000 | 뷰 전체 트리 상한 (초과분 truncate) |
| densityMultiplier | 1 | 밀도 배율 |
| baseTreesPerHectare | 300 | 밀도 1.0 기준 ha당 나무 수 |
| cellSize | 100 | 샘플링 그리드 셀 크기(m) |
| heightVariation | 0.2 | 수고 ±변동 비율 |
| renderer | 'point' | 'auto': 거리별 Point→Billboard→GLB 전환 |
| rendererOptions.maxModelCount | 1,000,000 | GLB 인스턴스 총 상한 |
| rendererOptions.maxModelsPerTile | 1,000,000 | 타일당 GLB 상한 |
| rendererOptions.minModelSize | 0 | GLB 최소 크기(m) 클램프, 0=off |
| rendererOptions.billboardFallback | false | GLB 초과/실패 시 빌보드 대체 (기본은 생략) |
| terrainProvider | null | 지정 시 나무를 terrain 높이에 배치 |
| terrainLevel | 'auto' | terrain 샘플 레벨 ('auto' = 타일 레벨 연동) |
런타임 API
layer.setShow(bool); // 표시 토글 (로드 유지)
layer.remove(); layer.add(); // 완전 언로드 / 재로드
layer.setRenderer('model'); // 렌더러 전환
layer.setDensityMultiplier(0.5);
layer.setMaximumTreeCount(2_000_000);
layer.setTerrainProvider(provider); // null이면 해제
layer.setTileColorize(true); // 디버그: 타일별 색 틴트
layer.onStatsChanged((stats) => {}); // 타일/트리 수, 단계별 타이밍
layer.getTileStates(); // 타일별 downloading|processing|loaded
layer.pickFeature(cartographic); // 위치의 임상 폴리곤 속성 조회데모 실행
cp .env.example .env # VITE_MVT_URL을 자신의 서버로
npm install
npm run dev # http://localhost:5173데모 UI에서 Basemap/MVT Source/Terrain URL, 밀도·상한·디버그 오버레이 (타일 상태색 바운더리, 타일 colorize, terrain 그리드)를 조절할 수 있습니다.
Martin 서버 구축
임상도 GPKG만 있고 타일 서버가 없다면 server/README.md 참고 — PostGIS + ogr2ogr 자동 import + Martin이 docker compose 하나로 구성됩니다.
